0

在类组件中,当我们想使用反应上下文将对象传递给上下文提供者的值时,我们有一种方法可以避免重新渲染问题。下面是代码

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      text: "",
      contextState: {
        count: 0,
        increment: this.increment
      }
    };
  }

  increment = () => {
    this.setState({
      contextState: {
        ...this.state.contextState,
        count: this.state.contextState.count + 1
      }
    });
  };

  onChange = e => {
    const { value, name } = e.target;
    this.setState({ [name]: value });
  };

  render() {
    return (
      <CountContext.Provider value={this.state.contextState}>
        <div style={styles}>
          <input name="text" value={this.state.text} onChange={this.onChange} />
          <div>Count: {this.state.contextState.count}</div>
          <Container1 />
          <Container2 />
        </div>
      </CountContext.Provider>
    );
  }
}

我们将 this.state.contextState 设置为 CountContext.Provider 的值。因此,当用户在输入元素中键入任何内容时,不会导致<Container1 />重新<Container2 />渲染。这里是代码沙箱:https ://codesandbox.io/s/qqx1jqk8mj?file=/src/index.js:260-1105

我正在尝试将其转换为钩子。这是代码沙箱https://codesandbox.io/s/affectionate-gauss-duk64?file=/src/index.js但计数器无法正常工作。请问哪部分错了?谢谢

4

1 回答 1

1

在您的钩子组件中,您只需要使用函数式 setState 方法。

setContextState(prevState=>newState)

在您的代码中:https ://codesandbox.io/s/admiring-shtern-g6oll?file=/src/index.js

  const [contextState, setContextState] = useState({
    count: 0,
    increment: () => {
      setContextState(prev=>({
        ...prev,
        count: prev.count + 1
      }));
    }
  });

您需要这样做的原因是状态值将永远不会更新,因为它周围的闭包。contextState.count将始终保持为 0,因为它是最初设置状态时的值 ( 0),并且不会改变。

于 2021-08-06T02:28:40.730 回答