reactjs - 为什么react中的 "lifting state up"并不总是有效?

标签 reactjs redux react-redux

我正在阅读 redux 文档,它说:

...the simplicity can break down when we have multiple components that need to share and use the same state, especially if those components are located in different parts of the application. Sometimes this can be solved by "lifting state up" to parent components, but that doesn't always help.

在阅读 redux 文档之前,我一直认为在整个应用程序中共享状态实际上可以通过提升状态来完成,但 redux 文档只是说如果没有任何示例或解释,它并不总是有帮助。

任何人都可以举例说明何时提升状态没有帮助吗?我是 React 新手,还没有遇到必须使用 redux 等库在全局范围内共享状态的问题。

最佳答案

并不是说它不能完成。更重要的是,它会让事情变得非常丑陋并迫使螺旋钻探。如果我有一个全局用户,我不会被迫通过其他组件将该用户状态向下传递 6 个级别,这些组件除了将其进一步转发到 使用它。

这就是 React.Context 的要点和 Redux。

下面是使用钻取和上下文的 2 个示例。 <Parent/>渲染状态,<Middle/>什么都不做,<Child/>渲染状态并让您通过按钮设置它。这是一个显示它们依赖关系的表格

<表类=“s-表”> <标题> 组件 需要状态 需求设置者 <正文> 父级 是 否 中 否 否 子项 是 是

钻孔

考虑下面使用钻孔的示例。 <Parent/>托管状态,包括实际值以及更改它的方法,即使它只关心显示它。 <Middle/>根本不关心状态,但无论如何都必须了解它才能将其转发到 <Child/><Child>需要了解有关状态的一切,因为它想要渲染它并改变它。

const {useState} = React;

const Parent = () => {
  const [some, setSome] = useState("foobar");

  return (
    <div>
      <h2>Parent</h2>
      <div>I care about some because I want to display it: "{some}"</div>
      <Middle some={some} onThing={v => setSome(v)} />
    </div>
  )
};

const Child = ({some, onThing}) => (
  <div>
    <h2>Child</h2>
    <div>I care about some a lot and will render it: "{some}" and do stuff to change it</div>
    <button onClick={() => onThing("hello")}>Change to "hello"</button>
    <button onClick={() => onThing("world")}>Change to "world"</button>
  </div>
);

const Middle = ({some, onThing}) => (
  <div>
    <h2>Middle</h2>
    <div>I don't care about some at all and try not to do anything with it</div>
    <Child some={some} onThing={onThing} />
  </div>
);

const App = () => (
  <div>
    <h1>This is the App Using Drilling</h1>
    <Parent />
  </div>
);

ReactDOM.render(
  <App/>,
  document.getElementById("app")
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="app"></div>

上下文

现在考虑使用上下文的示例。 <Parent/>只关心实际值,并且只将其从上下文中提取出来。 <Middle/>非常简单,没有 Prop 。它只是渲染<Child/><Child/>看起来非常相似,除了它从 useContext 获取状态和 setter 。而不是它的 Prop 。

const {useState, useContext, createContext} = React;

const SomeContext = createContext(null);

const SomeProvider = ({children}) => {
  const someState = useState("foobar");

  return (
    <SomeContext.Provider
      value={someState}
      children={children}
    />
  )
}

const Parent = () => {
  const [some] = useContext(SomeContext);

  return (
    <div>
      <h2>Parent</h2>
      <div>I care about some because I want to display it: "{some}"</div>
      <Middle />
    </div>
  );
};

const Child = () => {
  const [some, setSome] = useContext(SomeContext);

  return (
    <div>
      <h2>Child</h2>
      <div>I care about some a lot and will render it: "{some}" and do stuff to change it</div>
      <button onClick={() => setSome("hello")}>Change to "hello"</button>
      <button onClick={() => setSome("world")}>Change to "world"</button>
    </div>
  );
};

const Middle = () => (
  <div>
    <h2>Middle</h2>
    <div>I don't care about some at all and try not to do anything with it</div>
    <Child />
  </div>
);

const App = () => (
  <div>
    <h1>This is the App Using Context</h1>
    <SomeProvider>
      <Parent />
    </SomeProvider>
  </div>
);

ReactDOM.render(
  <App/>,
  document.getElementById("app")
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="app"></div>

关于reactjs - 为什么react中的 "lifting state up"并不总是有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68487077/

相关文章:

javascript - redux-saga 根据 UI 组件状态有条件地订阅 worker

reactjs - 在 redux 中调度后如何返回操作结果?

javascript - Prop 数据未渲染

javascript - React-select 不显示字段中选择的值

mysql - 我正在尝试显示我用 multer 上传到后端的图像

javascript - ES6 语法模式下 Redux 未定义

reactjs - 如何在 react 之外访问 redux 中的当前存储状态?

react-native - 在使用 redux-persist 存储重新水化之前加载初始状态的默认值

javascript - removeTodo 操作未从状态中删除

javascript - 用户路由器();在getServerSideProps :next js里面