【问题标题】:React / Redux Components not re-rendering on state changeReact / Redux 组件不会在状态更改时重新渲染
【发布时间】:2017-12-21 00:49:33
【问题描述】:

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

https://codesandbox.io/s/jjy9l3003

所以基本上我有一个 App 组件触发一个动作,如果屏幕被调整大小并且小于 500 像素(如果更高,则为 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 函数?

【问题讨论】:

    标签: reactjs react-redux


    【解决方案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 重新渲染您的组件,您必须在 render 函数中使用“this.props”(因为每次道具更改时都会调用渲染):

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2020-03-03
        • 1970-01-01
        • 2018-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-22
        • 1970-01-01
        相关资源
        最近更新 更多