反应状态和条件渲染

时间:2021-05-04 10:31:00

标签: reactjs

我有一个关于条件渲染的问题。我在 View1 和 View2 组件中有一个状态(计数器)。我使用按钮在视图之间切换。当我在组件之间切换时,如何防止计数器初始化为其原始状态。我需要每个组件都有自己的计数器,当我在 View1 和 View2 之间切换时,该计数器不会返回到其原始状态。

https://codesandbox.io/s/vigorous-boyd-rbx3d

这是一个小演示,我需要用它在两种形式之间切换(不会丢失值)。

2 个答案:

答案 0 :(得分:0)

您应该在 view1view2 的父级中定义计数器状态,然后传递计数器值和函数来更新两个组件中的计数器值。

所以你的父组件会是这样的:

export default function App() {
  const [view, setView] = React.useState(1);
  const [counter, setCounter] = React.useState(1);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={() => setView(1)}>View 1</button>
      <button onClick={() => setView(2)}>View 2</button>
      {
        {
          1: (
            <>
              <View1 key={1} setCounter={setCounter} counter={counter} />
            </>
          ),
          2: (
            <>
              <View2 key={2} setCounter={setCounter} counter={counter} />
            </>
          )
        }[view]
      }
    </div>
  );
}

您的子组件将如下所示:

View1.js

export default function View1(props) {
  return (
    <div>
      View111
      <button onClick={() => props.setCounter(props.counter + 1)}>Plus</button>
      {props.counter}
    </div>
  );
}

view2.js

export default function View2(props) {
  return (
    <div>
      View22222
      <button onClick={() => props.setCounter(props.counter + 1)}>Plus</button>
      {props.counter}
    </div>
  );
}

这里是Demo

答案 1 :(得分:0)

您需要提升视图状态或保持它们处于挂载状态。

具有状态提升的第一个变体可能如下所示:

import React, { useCallback } from "react";

function View({ label, counter, increment }) {
  return (
    <div>
      {label}
      <button onClick={increment}>Plus</button>
      {counter}
    </div>
  );
}

const labels = ["View111", "View222"];

export default function App() {
  const [view, setView] = React.useState(1);

  const [counters, setCounters] = React.useState([1, 1]);

  const increment = useCallback(() => {
    setCounters((v) => v.map((vv, idx) => (idx === view - 1 ? vv + 1 : vv)));
  }, [view]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={() => setView(1)}>View 1</button>
      <button onClick={() => setView(2)}>View 2</button>
      <View
        counter={counters[view - 1]}
        increment={increment}
        label={labels[view - 1]}
      />
    </div>
  );
}

保持视图隔离的第二个变体可能如下所示:

export default function App() {
  const [view, setView] = React.useState(1);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={() => setView(1)}>View 1</button>
      <button onClick={() => setView(2)}>View 2</button>
      <div style={{ display: view === 1 ? undefined : "none" }}>
        <View1 key={1} />
      </div>
      <div style={{ display: view === 2 ? undefined : "none" }}>
        <View2 key={2} />
      </div>
    </div>
  );
}