React-table: Table does not re-render when using redux for pageSize

Created on 20 Sep 2017  路  15Comments  路  Source: tannerlinsley/react-table

// myTable.js

class MyTable extends React.Component {
  render() {
    return (
      <div>
        <h1>{this.props.pageSize}</h1>
        <ReactTable
          data={this.props.data} // not from redux
          columns={this.props.columns} // not from redux
          pageSize={this.props.pageSize} // from redux
        />
      </div>
    );
  }
}

const mapStateToProps = state => ({ pageSize: state.pageSize });

export default connect(mapStateToProps, null)(MyTable);
// customTable.js

class CustomTable extends React.Component {
  componentWillMount() {
    this.props.loadData();
  }
  render() {
    const columns = [...];
    return (
      <MyTable data={this.props.data} columns={columns} />
    );
  }
}

const mapStateToProps = state => ({ data: state.something });
const mapDispatchToProps = dispatch => ({ loadData: () => { dispatch(loadSomething()); } });

export default connect(mapStateToProps, mapDispatchToProps)(CustomTable);

Note that the value inside <h1> changes, but the table does not re-render. If I map the pageSize in CustomTable and send it down as a normal prop, it works. The problem occurs when I have a container inside a container.

Most helpful comment

Had the same issue. solved it by adding a key to the child component to force rendering:
<ReactTable key={this.props.uniqueKey} ...

in you sandbox example adjust it as follows:
<ReactTable key={this.props.pageSize} ...

All 15 comments

With the code as provided, I am not sure how the pageSize prop is getting to MyTable as it is not passed as a prop to MyTable (so not sure how the h1 would be displaying it correctly). The only props that seem to be passed to MyTable are data and columns.

Maybe you could run up a codesandbox to show the problem working.

@gary-menzel The pageSize prop is "sent" from redux state:

const mapStateToProps = state => ({ pageSize: state.pageSize }); // this sets this.props.pageSize
export default connect(mapStateToProps, null)(MyTable);

@erica93k I admin I am not an expert but it "feels" like the second mapStateToProps is happening higher up and potentially cancelling out the inner one. What I still don't understand is why it would be appearing in H1 and not being pushed into the ReactTable.

This is partially supported by you saying that if you pass it down specifically on the "normal" props "it works". So it sounds like a conflict from the multiple redux connect calls. I would not have thought you would using connect twice but would pass anything from the top-level down as normal props to the lower levels. But, as I said, I am not really familiar with the idiosyncrasies of Redux.

You may need to put in some lifecycle methods and/or see what the values in this.props are at that point before you use them - like a console.log(this.props) just before the return where you are outputting the H1 and ReactTable.

@gary-menzel

I created a sandbox trying reproduce the issue:

https://codesandbox.io/s/k5w9640ov3 - this works fine (only the parent component is a container)
https://codesandbox.io/s/jjk93nv2k3 - this has some issues (the pagination is not updating, the empty rows are not displayed, like in the first example & if you change the current page then try to change the pageSize it doesn't work at all)

Hope this helps.

I can see the strange behaviour. But it also feels "strange" to me to be updating the data in one connect HOC container function but updating the pageSize in a different one (I don't use Redux but there is similar layering in the container system that I use - but if I have multiple containers they are completely responsible for their own domain). Unless there was a strong use case to split these I would have put them all at the top (like your working example). I think, given the involvement of Redux (and my lack of experience with it), that @tannerlinsley is probably better to maybe comment on this. However, pageSize is sort of paired up with onPageSizeChange - this could be impacting it but I doubt that. I don't think the problem is a ReactTable one (other than the possible confusion with the full control with pageSize and onPageSizeChange)

I will have multiple tables, and if I change the pageSize, it should be changed for all of the tables. That's why I included it in MyTable.

I will try to debug it with onPageSizeChange.

Again - I'm no Redux expert (I had to look up the connect method). But I would probably just "connect" my top level component with all the functionality it needed and then pass it down in props. If I want to reuse one of the embedded components elsewhere, I'd connect it again there.

Had the same issue. solved it by adding a key to the child component to force rendering:
<ReactTable key={this.props.uniqueKey} ...

in you sandbox example adjust it as follows:
<ReactTable key={this.props.pageSize} ...

@redlock
It seems to work: https://codesandbox.io/s/j4on9974jv, thanks!

Although, I am not sure if this is the proper fix or if it's a bug

I am still of the opinion that it is an interaction issue between the way the connect method of Redux works (not an issue with ReactTable) - especially considering it works fine with a single Redux connect wrapper container.

The MyTable component is being rerendered when the pageSize changes, only the ReactTable is not rerendered properly. I don't think it's a redux issue.

Well the tests I did (without Redux being involved and a multi wrapped component) work fine.

Hence why I believe is it is conflict between Redux connect and ReactTable - not the fault of ReactTable alone.

I see. I am happy with @redlock 's solution for now. Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

golan4ik picture golan4ik  路  18Comments

BenMGilman picture BenMGilman  路  22Comments

sshaginyan picture sshaginyan  路  21Comments

hassankhan picture hassankhan  路  51Comments

Grsmto picture Grsmto  路  100Comments