为什么即使道具改变也不会触发渲染

时间:2017-11-21 11:54:41

标签: reactjs redux

我一直在使用react + redux,但在codepen上可以帮助我以下情况:

const {createStore } = Redux;
const { Provider, connect } = ReactRedux;

const store = createStore((state={name: 'ron'}, action) => {
  switch(action.type) {
    case 'changeName': return {name: action.name};
    default: return state
  }
})

const Person = props => {
  const {name, dispatch} = props
  console.log(`rendering Person due to name changed to ${name}`)
  return (
    <div>
      <p> My name is {name} </p> 
      <button onClick={ () => dispatch({type: 'changeName', name: 'ron'}) } > Change to Ron </button>
      <button onClick={ () => dispatch({type: 'changeName', name: 'john'}) } > Change to John</button>
    </div>  
  )
}

const App = connect(state=>state)(Person)

ReactDOM.render(
  <Provider store={store}><App/></Provider>,
  document.getElementById('root')
);

这很简单反应app,但我无法解释:

  1. 使用一个reducer初始化redux store,其initValue为{name: 'ron'}
  2. 点击Change to ron按钮,它会发送{type: 'changeName', name: 'ron'}
  3. 当reducer获得此操作时,它将生成一个全新的状态{name: 'ron'},虽然该值与原始状态相同,但它们是不同的标识,应该是不同的标识。
  4. 如果道具发生变化,即使值相同,也应重新渲染功能组件。所以我想调用render函数,控制台应该输出rendering Person due to...。但是,它没有发生。
  5. 我想知道为什么反应功能组件在更改道具标识时拒绝再次渲染(尽管值相同)

1 个答案:

答案 0 :(得分:1)

你的connect(state=>state)(Person)我认为这没错,但这很奇怪。

根据文档https://redux.js.org/docs/basics/UsageWithReact.html,您可以分离状态和操作调度程序,通常命名为mapStateToProps和mapDispatchToProps。

所以,我建议你这个代码:

const mapStateToProps = state => ({
  user: state.user
})

const mapDispatchToProps = dispatch => ({
  updateName: (name) => dispatch(changeName(name)),
})

class DemoContainer extends Component {
  constructor() {
    super();
  }

  render() {
    return (
      <div>
        <p> My name is {this.props.user.name}</p> 
      <button onClick={ () => this.props.updateName('ron') } > Change to Ron </button>
      <button onClick={ () => this.props.updateName('john') } > Change to John</button>
      </div>
    );
  }

}
const Demo = connect(
  mapStateToProps,
  mapDispatchToProps
)(DemoContainer)

export default Demo

我的减速机:

const initialState = { name: 'John'}

const user = (state = initialState, action) => {
  switch (action.type) {
    case "CHANGE_NAME":
      return {
        name: action.name
      }
    default:
      return state
  }
}

export default user

我的行动:

export const changeName = ( name ) => ({
  type: "CHANGE_NAME",
  name,
})

您可以在此处查看我的所有代码:https://stackblitz.com/edit/react-tchqrg

我有一个组件类,但你也可以使用像你一样的连接功能组件。