【问题标题】:State Change Causing Sidebar Reload状态更改导致侧边栏重新加载
【发布时间】:2019-09-04 02:19:03
【问题描述】:

我正在建立一个在线商店。单击结帐按钮时,侧边栏会滑入视图,显示购物车中的项目列表。购物车里面是它的物品清单。您可以通过切换 Bootstrap-React 提供的 Form.Control 元素中的向上/向下箭头来更改数量。

我的代码的工作方式是,当您切换向上/向下箭头以添加或减少产品数量时,父级中的状态会根据您的购物车中的内容发生变化。这会触发子购物车侧边栏关闭然后重新打开。我不希望这种情况发生!侧边栏应保持打开状态。

我尝试了两件事;一种是使用 event.preventDefault() 尝试并使其不刷新页面,但这不起作用。

另一件事是尝试使用shouldComponentUpdate 并检查项目数量是否已更改,然后阻止应用重新渲染。这是我使用的代码:

  shouldComponentUpdate(nextProps, nextState) {
    if (
      nextState.cart &&
      nextState.cart.length > 0 &&
      this.state.cart.length > 0
    ) {
      console.log("Next state cart num= " + nextState.cart[0].num)
      console.log("curr state cart num= " + this.state.cart[0].num)
      if (nextState.cart[0].num != this.state.cart[0].num) {
        return false;
      }
    }

    return true;
  }

问题是我以前和以后的道具是一样的!因此,我无法编写任何代码来防止重新渲染项目数量的变化。

谁能给点建议?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    如果您的组件正在重新渲染,但它的 props 和 state 根本没有改变,那么您可以使用 React memo 来阻止这种情况,如果您使用的是函数,或者如果您使用的是基于类的组件然后扩展 @ 987654322@ 而不是 React.Component。

    两种方式都会做一个浅的 prop 和 state 比较,并根据所述比较的结果决定是否应该重新渲染。如果您的下一个 props 和 state 与之前相同,则不会触发重新渲染。

    这是codepen example,您可以决定使用哪一个。

    class App extends React.Component {
        state = {
            count: 0
        };
    
        handleClick = event => {
            event.preventDefault();
            this.setState(prevState => ({ count: prevState.count + 1 }));
        };
    
        render() {
            return (
                <div>
                    <span>Click counter (triggers re render): {this.state.count}</span>
                    <button style={{ marginLeft: "10px" }} onClick={this.handleClick}>
                        Click me to re render!
                    </button>
                    <SingleRenderClassComponent />
                    <SingleRenderFunctionComponent />
                    <AlwaysReRenderedClassComponent />
                    <AlwaysReRenderedFunctionComponent />
                </div>
            );
        }
    }
    
    class SingleRenderClassComponent extends React.PureComponent {
        render() {
            console.log("Rendered React.PureComponent");
            return <div>I'm a pure component!</div>;
        }
    }
    
    const SingleRenderFunctionComponent = React.memo(
        function SingleRenderFunctionComponent() {
            console.log("Rendered React.memo");
            return <div>I'm a memoized function!</div>;
        }
    );
    
    class AlwaysReRenderedClassComponent extends React.Component {
        render() {
            console.log("Rendered React.Component");
            return <div>I'm a class!</div>;
        }
    }
    
    function AlwaysReRenderedFunctionComponent() {
        console.log("Rendered function component");
        return <div>I'm a function!</div>;
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    
    

    【讨论】:

    • 我非常感谢您的回复——当我第一次阅读它时,这似乎是一个很好的答案。不幸的是,在将我的组件更改为 PureComponent 之后,我没有任何运气。鉴于您的逻辑,我不确定为什么它不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多