javascript 如何在react中管理复杂的项目列表?

pod7payv  于 2023-02-28  发布在  Java
关注(0)|答案(4)|浏览(122)

我正在构建一个分面搜索组件。我在弄清楚如何以及在哪里处理状态时遇到了麻烦。

溶液#1

父组件管理状态**-使用简化器管理所有组件并向下传递状态

**缺点:**子组件非常复杂(自动完成,焦点状态),并且在父级更新状态会导致子组件重新呈现。这意味着子组件的焦点状态和建议不能很好地工作。
**优点:**设计更简洁,可在一个减速器中处理状态

溶液#2

子组件管理它们自己的状态(如不受控制的组件)。父组件仅管理创建、删除新的复杂组件。子组件在知道它们已完成(失去焦点)时更新父组件上的引用。
**缺点:**管理两个状态和重复的键错误
**优点:**子组件按预期工作

帮助和建议

这两种解决方案都很难实现,但到目前为止,我在解决方案#2上运气更好。

有什么好的例子吗?看起来可编辑的待办事项列表也会有类似的问题。
我喜欢解决方案#1的想法,但我认为我需要一种推迟更新状态的方法。

pwuypxnk

pwuypxnk1#

当然,您需要单独管理状态,更像选项2。组件并不意味着只能控制或不控制,您需要考虑其中的哪些信息应该控制(通过属性),哪些信息应该不控制(通过状态)。
为了确定您的情况,我建议按照官方指南thinking-in-reacttic-tac-toe重新考虑您的组件。
在这里,我将直接跳到步骤4:确定您所在州的地址
心态是
1.标识基于该状态呈现内容的每个组件。
1.查找它们最近的公共父组件-层次结构中所有组件之上的组件。
1.决定州政府应该住在哪里
很明显,您的子组件需要搜索文本和选项列表来呈现或更改自身,而父组件不需要这些值,父组件只需要一个包含其静态值(所选值)的子组件列表。
实时的变化应该发生在内部,但是每当值被决定时,它应该将状态提升到父级。这是因为从父级的Angular 来看,它最终应该需要收集来自子级的所有值,如果状态没有被存储,那么它可能成为从父级到子级的"询问",这不是一个好的方法。并且它有利于实现具有多个子级的逻辑。另一方面,下拉数据和过滤器文本对父级没有用,它们更像是一种"临时状态",最好留在组件内部,因此不需要将它们抬起。
所以在我看来,我会这样安排国家结构:
父代:state: [{type:'',value:''}...]
父级渲染子级:

for(int i=0; i < state.length; i++){ 
    <Child ...state[i] onValueChanged={(newValue)=> changeState(i,newValue)} />
}

子 prop :{type:'',value:'',onValueChanged:(newValue)=>void}
子状态:{data:[], filter:'', focused: false}
child的data应使用不同的给定类型加载。
在子组件内部,UI使用其自己的状态呈现。
在选择该值的同时,child调用onValueChanged通知parent该值发生了变化,从而限制了parent触发的重新渲染。
每当父节点需要输出值时(如将搜索文本推到后端),可以直接使用状态。
在组件级的所有这些安排完成后,您可以毫不费力地将父状态管理切换到reducer。

g6ll5ycj

g6ll5ycj2#

当你的状态很复杂,并且被多个兄弟/子状态使用时,你肯定希望这个状态存在于公共父状态上。解决方案2,兄弟状态各自管理一个复杂状态的一部分,这将成为一场维护的噩梦--因为你必须在处理一个状态时记住所有这些不同的状态。
另一件要记住的事情是状态本身的形状,对于由多种类型组成的状态,useReducer()将是更好的选择。
例如:复杂状态是:

... = usestate({
"user" : {
"name": "",
"age" : null},
skills: [],
rate: 50,
company: "default",
reviews: [],
});

要更新这个状态,你必须写很多类型检查和不同类型的spread。有些是数组,有些是int,有些是String,等等。
在这一点上,reducer更有意义。reducer通过一个动作和一个有效负载来处理状态。状态逻辑则存在于这些组件的单独文件中。
我认为这是应该走的路:https://www.aleksandrhovhannisyan.com/blog/managing-complex-state-react-usereducer/

k75qkfdt

k75qkfdt3#

据我所知,你有2个下拉菜单,根据你选择的选项,你将获取一些数据。为此,你可以创建一个可重用的Dropdown组件,并在当前组件中呈现它们,如下所示:

const CityDropDownOptions = [
  { label: "la", value: "los angeles" },
  { label: "ny", value: "new york" },
];

const CountryDropDownOptions = [
  { label: "uk", value: "England" },
  { label: "tr", value: "Turkey" },
];
const Search = () => {
  const [city, setCity] = useState(CityDropDownOptions[0]);
  const [country, setCountry] = useState(CountryDropDownOptions[0]);

  return (
    <>
      <Dropdown
        selected={city}
        // this is the callback we send down to the Dropdown component
        onSelectedChange={setCity}
        // you render this in the Dropdown component
        options={CityDropDownOptions}
      />
      <Dropdown
        selected={country}
        onSelectedChange={setCountry}
        options={CountryDropDownOptions}
      />
      {/* you somehow trigger the api request */}
      <button onClick={() => search(city.value, country.value)}>search</button>
    </>
  );
};
yvt65v4c

yvt65v4c4#

也许这太简单了,但是为什么不在选择第一个下拉菜单时调用一个函数并生成第二个下拉菜单呢?
当用户选择第一个下拉列表时,根据第一个下拉列表提交的数据生成第二个下拉列表
变更功能示例:https://stackoverflow.com/a/28868135/15038900

相关问题