Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React中的共享状态会更新其余组件以及当前组件_Javascript_Reactjs_React Hooks_Setstate - Fatal编程技术网

Javascript React中的共享状态会更新其余组件以及当前组件

Javascript React中的共享状态会更新其余组件以及当前组件,javascript,reactjs,react-hooks,setstate,Javascript,Reactjs,React Hooks,Setstate,我有一个用例,其中有4个select组件共享相同的状态。问题是,当用户从一个选项中选择一个选项时,其他选项不应显示该选项,以此类推。这个问题很简单而且解决了。执行此操作时,我将更新共享状态,因此所有4个选择都将由react重新渲染,因此我将从选择中丢失所选值。见附件GIF 有人能指出一个解决方案吗?我可以用最少的状态和更少的重新渲染来解决这个问题 附上以下全部代码: const SendTroops = () => { const [planets, setPlanets] =

我有一个用例,其中有4个select组件共享相同的状态。问题是,当用户从一个选项中选择一个选项时,其他选项不应显示该选项,以此类推。这个问题很简单而且解决了。执行此操作时,我将更新共享状态,因此所有4个选择都将由react重新渲染,因此我将从选择中丢失所选值。见附件GIF

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

附上以下全部代码:

  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 >
  );
};
const sendForems=()=>{
常数[行星,集合行星]=useState([]);
const[vehicles,setVehicles]=useState([]);
const constructState=(数据)=>{
常数arr=[];
设obj={};
for(设i=0;i<4;i++){
obj[i]=数据;
}
方位推力(obj);
返回arr;
};
useffect(()=>{
常量getPlanets=async()=>{
试一试{
const response=await callAPI(PLANETS.url,PLANETS.method);
const data=wait response.json();
设置行星(状态(数据));
}捕捉(错误){
控制台日志(err);
}
}
const getVehicles=async()=>{
试一试{
const response=wait callAPI(VEHICLES.url,VEHICLES.method);
const data=wait response.json();
设置车辆(施工状态(数据));
}捕捉(错误){
控制台日志(err);
}
};
获取行星();
getVehicles();
}, []);
常量ShowInputs=(n)=>{
常量选项=[];
for(设i=0;i
onVehicleChange(e,i)}/>
))
}
返回选项;
}
const onDestinationChange=(e,索引)=>{
const selectedName=e.target.value;
常量值=对象值(行星[0]);
设obj={};
for(设i=0;i<4;i++){
如果(i==索引)obj[i]=值[i];
否则{
obj[i]=值[i]。过滤器((值)=>value.name!==selectedName);
}
}
const updatedPlanets=[].concat([obj]);
设置行星(更新的行星);
};
const onVehicleChange=(e)=>{
console.log(如target.value);
};
常数onReset=(e)=>{
e、 预防默认值();
};
返回(

为您的部队选择要搜索的行星

{ShowInputs(4)} ); };
只要记住行星列表中所选行星的索引和该行星所选元素的索引即可。然后仅在先前选择的
选择
上显示所选选项

这样,您必须在状态中再添加两个字段:

  • 行星列表中所选行星的索引(默认值为
    -1
    或负值)
  • 选择它的
    元素的索引(在您的例子中,它是
    ShowInputs()
    for
    循环的迭代器
    i

  • 然后,每当用户选择某个对象时(使用
    onDestinationChange()
    )更新该字段。

    只要记住行星列表中所选行星的索引和选择该行星的
    元素的索引即可。然后仅在先前选择的
    选择
    上显示所选选项

    这样,您必须在状态中再添加两个字段:

  • 行星列表中所选行星的索引(默认值为
    -1
    或负值)
  • 选择它的
    元素的索引(在您的例子中,它是
    ShowInputs()
    for
    循环的迭代器
    i
  • 然后,每当用户选择某个内容时(使用
    onDestinationChange()
    )更新该字段