将组件存储在状态中是个好主意吗?

时间:2021-04-02 12:01:33

标签: reactjs redux

将整个 React 组件存储在组件状态或 redux 状态是一种好习惯吗?是的,它是可选的,因为我们可以在状态中存储一个字符串并有条件地渲染组件,但在某些情况下,将组件存储在状态中更简单。

例如

const [ components ]  = useState([
    { id: 1, component: <Login />, title: `Login` },
    { id: 2, component: <Register />, title: `Register` },
])

但是组件可能很大,我想知道这是否有什么不同。这是一种不好的做法吗?

2 个答案:

答案 0 :(得分:1)

实际上,它是有效的,但实际上这不是一个好主意,ReactJS 很难比较它,在状态对象中对其进行修正或修改或删除它。

为您的状态使用简单的字符串,将组件存储在静态对象中,然后使用它们:

const StaticList = {
  Login, // <<== pay attention, I don't use JSX, I pass the imported name
  Register,
};

const YourComponent = () => {
  const [ components ]  = useState([
    { id: 'one', cn: 'Login', title: `Login` },
    { id: 'two', cn: 'Register', title: `Register` },
  ]);


  return (
    <div>
      {components.map(({ id, cn, title }) => {
        const Comp = StaticList[cn];

        return (
          <div key={id}>
            <span>{title}</span>
            <Comp />
          </div>
        );
      })}
    </div>
  );

与上面类似,这是一个简单的示例。

答案 1 :(得分:0)

你问: “以状态存储组件是个好主意吗? 将整个 React 组件存储在组件状态或 redux 中是一种好习惯吗? 状态? [...] 但在某些情况下,将组件存储在状态中更简单。 这是一种不好的做法吗?”

不,这不是一个好主意。 不,这不是一个好习惯。 不,那从未如此简单。 是的,这绝对是一种不好的做法。

React 基于一个简单而强大的核心概念:函数接收一些值(属性)并返回要呈现为当前值集的直接结果的元素。 (所有其他概念都只是辅助:状态、副作用、生命周期、合成事件、参考、记忆、快子发射器和 numberwang)

存储元素供以后使用直接打破了这个核心概念。您可能会面临与当前属性集不对应的陈旧元素。 (即使您的元素没有任何属性作为输入,您也不会通过将它们置于状态中获得任何有用的东西,请继续阅读。)

创建反应元素并将它们置于状态的预期用途是什么?想要解决什么感知问题? 我可以找出你可能试图通过这样做来实现的两件事: 1. 有条件地呈现元素的方法;和 2. 以某种方式优化创建新反应元素的次数。 对于这两个目标,将 react 元素放入 state 的操作方式是不合适的。

为了这两个目标,React 提供了简单的解决方案: 条件渲染元素是这样实现的:

const [showPrompt, setShowPrompt] = useState(false);
// ...
<div>
  { showPrompt && <ConfirmationPrompt /> }
</div>

或使用道具

const MyComponent = ({showPrompt}) => {
// ...
<div>
  { showPrompt && <ConfirmationPrompt /> }
</div>

这很简单,很清楚,是正确的。什么都没坏。未来的维护者不会被迫诅咒您或毒害您的香草奶茶拿铁。

如果你有理由认为你的渲染函数很重并且你想减少它运行的次数,你可以使用 useMemo 钩子(在你的渲染函数中记住计算结果)或者你可以将整个组件包装在 React.memo() 中,因此只有在 props 更改时才会重新渲染。 (只有当您可以实际测量任何差异时,才应使用这两种机制。)

const primeNumbers = useMemo(() => calculatePrimeNumbers(limit), [limit]);
const MyComponent = React.memo((props) => {
  /* render using props */
});