React / Redux组件不会在状态更改时重新呈现

时间:2017-12-21 00:49:33

标签: reactjs react-redux

我认为这个问题已经回答了几次,但我找不到具体案例。

https://codesandbox.io/s/jjy9l3003

所以基本上我有一个App组件触发一个动作,如果屏幕调整大小并且小于500px(如果它更高则为false),将状态调用“isSmall”更改为true。

class App extends React.Component {
...
resizeHandeler(e) {
    const { window, dispatch } = this.props;
    if (window.innerWidth < 500 && !this.state.isSmall) {
      dispatch(isSmallAction(true));
      this.setState({ isSmall: true });
    } else if (window.innerWidth >= 500 && this.state.isSmall) {
      dispatch(isSmallAction(false));
      console.log(isSmallAction(false));
      this.setState({ isSmall: false })
    }
  };

  componentDidMount() {
    const { window } = this.props;
    window.addEventListener('resize', this.resizeHandeler.bind(this));
  }
...

我还有一个名为HeaderContainer的组件,它是App的子级并连接到Store并且状态为“isSmall”,我希望当“isSmall”更改状态时,此组件会重新呈现...但它不是

class Header extends React.Component {

  constructor(props) {
    super(props);

    this.isSmall = props.isSmall;
    this.isHome = props.isHome;
  }
  ...
  render() {
     return (
      <div>
        {
          this.isSmall
          ?
           (<div>Is small</div>)
          :
           (<div>is BIG</div>)
        }
      </div>
    );
   }
   ...

即使我可以通过控制台看到redux实际上正在更新存储,Header组件也不会重新渲染。 有人可以指出我缺少的东西吗?

我是否误解了“connect()”redux-react函数?

2 个答案:

答案 0 :(得分:1)

组件只安装一次,然后只通过传递新的道具进行更新。因此,构造函数仅在mount之前被调用一次。这意味着您在此处设置的实例属性在安装组件的生命周期内永远不会更改。您必须直接访问this.props功能中的render()才能进行更新。您可以删除构造函数,因为在这种情况下他没有做任何有用的事情。

答案 1 :(得分:1)

在您发布的组件链接上查看代码,通过connect

连接到redux商店
const mapStateToProps = (state, ownProps) => {
  return {
    isHome: ownProps.isHome,
    isSmall: state.get('isSmall')
  }
}


export const HeaderContainer = connect(mapStateToProps)(Header);

这意味着您在mapStateToProps函数中访问的道具(isHome和isSmall)将从redux商店中获取并作为道具传递到您的组件中。

要让React重新渲染您的组件,您必须使用&#39; this.props&#39;在render函数内部(每当prop更改时调用render):

render() {
     return (
      <div>
        {
          this.props.isSmall
          ?
           (<div>Is small</div>)
          :
           (<div>is BIG</div>)
        }
      </div>
    );
   }

您在constructor中做得很好,但构造函数只在安装组件之前调用一次。您应该查看react生命周期方法:https://reactjs.org/docs/react-component.html#constructor

您可以完全删除Header.js文件中的constructor

您应该尽可能避免使用公共类属性(例如this.isSmall = props.isSmall;)作出反应,并在组件需要时使用React本地状态:https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class