0

I have seen below artilces, but my problem is different

http://redux.js.org/docs/faq/ReactRedux.html#react-not-rerendering

React-redux store updates but React does not

My Redux state has changed, why doesn't React trigger a re-render?

Chrome redux extension shows there is a diff (so no re-render is not by state mutation): enter image description here

But re-render not tigger.


I am using react-boilerplate as base, and I am using Immutable.js

reducer:

const initialState = fromJS({
  tags: [
    {
      id: 1,
      name:'t1',
      hexcolor: '#ccc',
      shortcut: 'ctrl+1',
      desc :'desc'
    }
  ],
});

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case REQUEST_TAGS_SUCCESSED:
      return state.set('tags', action.tags)
    case ADD_TAG_SUCCESSED:
      return state.update('tags', arr => arr.push(action.tag))
    default:
      return state
  }
}

Selectors

import { createSelector } from 'reselect';

export const selectTagPage = (state) => state.get('tagPage');

export const makeSelectTags = () => createSelector(
  selectTagPage,
  (state) => state.get('tags') && state.get('tags').toJS()
);

TagPage(Index.js)

export class TagPage extends React.PureComponent { 

  render() {
    const {tags, corpusId } = this.props;

    return (
      <div>
        <TagTable data={tags} {...this.props} ></TagTable>
      </div>
    );
  }
}

const mapStateToProps = createStructuredSelector({
  tags: makeSelectTags(),
});

function mapDispatchToProps(dispatch) {
  return {
    dispatch,
    requestTags: (corpusId) =>
    dispatch({ type:REQUEST_TAGS, corpusId }),
    updateTag: (id, new_tag) =>
    dispatch({ type: UPDATE_TAG, id , new_tag }),
    addTag: (tag) =>
    dispatch({ type: ADD_TAG, tag }),
    deleteTag: (tag) =>
    dispatch({ type: DELETE_TAG, tag }),
  };
}

const ConnectedTagPage = allCompose('tagPage', saga, reducer, mapStateToProps, mapDispatchToProps)(TagPage)

ConnectedTagPage.defaultProps = {
  tags: [],
}

export default ConnectedTagPage;

TagTable (TagPage's child)

class TagTable extends React.PureComponent {

  constructor(props) {
    super(props);

  }

  render() {
    const {classes, data, tagColormap, updateTag, addTag, deleteTag } = this.props;
    const trigger = <Button raised primary>新增</Button>

    return (
      <div>
        <TagSubmitDialog title={'TAG'} trigger={trigger} obj={null} handleSubmit={(tag) => addTag(tag)} ></TagSubmitDialog>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell>名称</TableCell>
              <TableCell>色值</TableCell>
              <TableCell>快捷键</TableCell>
              <TableCell>备注</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {data && data.map((n) => {
              return (
                <TableRow key={n.id}>
                  <TableCell>
                    {n.name}
                  </TableCell>
                  <TableCell>
                    {n.hexcolor}
                  </TableCell>
                  <TableCell>
                    { n.shortcut}
                  </TableCell>
                  <TableCell>
                    { n.desc}
                  </TableCell>
                </TableRow>
              );
            })}
          </TableBody>
        </Table>

      </div>
    );

  }

}

No matter how state change, TagTable does't change.

enter image description here

Debug detail:

select change too: enter image description here

page also get new tags: enter image description here

table get new tags:

enter image description here

Mithril
  • 12,947
  • 18
  • 102
  • 153

1 Answers1

0

OK, I found out that because of <TableRow key={n.id}> .

I have a initial data with id 1, and my test data id is 1 too. So it due to react not allow same key ...

Mithril
  • 12,947
  • 18
  • 102
  • 153