javascript - React 中的共享状态也会更新其余组件和当前组件

标签 javascript reactjs react-hooks setstate

我有一个用例,其中有 4 个选择的组件都共享相同的状态。问题是当用户从一个选项中选择一个选项时,其他选项不应显示该选项,依此类推。这个问题很简单并且已经解决了。这样做时,我正在更新共享状态,因此所有 4 个选择都由 react 重新渲染,因此我丢失了选择中的选定值。请参阅随附的 GIF。

有人可以指出一个解决方案,我可以使用最少的状态和更少的重新渲染来解决这个问题吗?

Use Case Example

附上下面的完整代码:

  const SendTroops = () => {
  const [planets, setPlanets] = useState([]);
  const [vehicles, setVehicles] = useState([]);

  const constructState = (data) => {
    const arr = [];
    let obj = {};
    for (let i = 0; i < 4; i++) {
      obj[i] = data;
    }
    arr.push(obj);
    return arr;
  };

  useEffect(() => {
    const getPlanets = async () => {
      try {
        const response = await callAPI(PLANETS.url, PLANETS.method);
        const data = await response.json();
        setPlanets(constructState(data));
      } catch (err) {
        console.log(err);
      }
    }

    const getVehicles = async () => {
      try {
        const response = await callAPI(VEHICLES.url, VEHICLES.method);
        const data = await response.json();
        setVehicles(constructState(data));
      } catch (err) {
        console.log(err);
      }
    };

    getPlanets();
    getVehicles();

  }, []);

  const ShowInputs = (n) => {
    const options = [];
    for (let i = 0; i < n; i++) {
      options.push((
        <div className="column" key={i}>
          <Select
            styles="select"
            name={`destination${i}`}
            options={(planets && planets[0]) ? planets[0][i] : []}
            onSelect={(e) => onDestinationChange(e, i)} />
          <Radio
            styles="radio"
            name={`vehicle${i}`}
            options={(vehicles && vehicles[0]) ? vehicles[0][i] : []}
            onSelect={(e) => onVehicleChange(e, i)} />
        </div>
      ))
    }
    return options;
  }

  const onDestinationChange = (e, index) => {
    const selectedName = e.target.value;
    const values = Object.values(planets[0]);
    let obj = {};
    for (let i = 0; i < 4; i++) {
      if (i === index) obj[i] = values[i];
      else {
        obj[i] = values[i].filter((value) => value.name !== selectedName);
      }
    }
    const updatedPlanets = [].concat([obj]);
    setPlanets(updatedPlanets);
  };

  const onVehicleChange = (e) => {
    console.log(e.target.value);
  };

  const onReset = (e) => {
    e.preventDefault();
  };

  return (
    < main >
      <p className="search-title">Select planets for your Troops to search</p>
      <form>
        <div className="row">
          {ShowInputs(4)}
        </div>
        <div className="row button-group">
          <Link to='/missionreport'>
            <Button styles="button" type="submit" text="Find Falcone" />
          </Link>
          <Button styles="button" type="reset" text="Reset" onPress={onReset} />
        </div>
      </form>
    </main >
  );
};

最佳答案

只需记住行星列表中所选行星的索引和 select 的索引即可该行星已被选择的元素。然后仅在 select 上显示所选选项之前选择的位置。

这样您就必须向您的州添加另外 2 个字段:

  1. 行星列表中所选行星的索引(默认为 -1 或负数)
  2. 索引<select>选择它的元素(在您的情况下,它是 ifor 循环的迭代器 ShowInputs() )。

然后在每次用户选择某些内容时更新该字段(使用 onDestinationChange() )。

关于javascript - React 中的共享状态也会更新其余组件和当前组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59590951/

相关文章:

javascript - 找到错误 : Method “simulate” is only meant to be run on a single node. 0

jquery - 如何使用 ES6/ES7 语法导入 jQuery UI?

javascript - 无限循环 React 钩子(Hook)

javascript - HTML5 Canvas 位图蒙版和绘图位图

javascript - 你能用 React hooks 提前回来吗?

javascript - map 存储中的 map

reactjs - 如何在另一个函数中使用 useEffect() 中声明的变量?

javascript - 覆盖react-pro-sidebar上的默认悬停

javascript - 是否有可能检测到 DOM 中的变化并使其不发生?

c# - 如何更新 GridView 页脚模板中标签的值?