如何在React MUI中切换已点击的开关而不是所有开关?

huangapple go评论54阅读模式
英文:

how to toggle clicked switch instead of all switches in react mui?

问题

这是我在父组件中的状态

const [feedbackType, setFeedbackType] = useState({
  manual: true,
  auto: false,
});

我将这个状态作为 props 传递给子组件。在子组件中,我有以下代码

const handleFeedbackChange = type => {
  setFeedbackType(prevState => ({
    ...prevState,
    manual: type === 'manual',
    auto: type === 'auto',
  }));
};

<div>
  <Switch
    checked={feedbackType.manual}
    onChange={() => handleFeedbackChange('manual')}
    name="manual-feedback"
    inputProps={{ 'aria-label': 'Manual feedback' }}
    color="primary"
  />
  <label htmlFor="manual-feedback">Manual Feedback</label>

  <Switch
    checked={feedbackType.auto}
    onChange={() => handleFeedbackChange('auto')}
    name="auto-feedback"
    inputProps={{ 'aria-label': 'Auto feedback' }}
    color="primary"
  />
  <label htmlFor="auto-feedback">Auto Feedback</label>
</div>

我的问题是,我在子组件上运行 map,所以如果有多个数据,就会有多个开关。所以当我尝试打开和关闭第一个开关时,会影响其他开关。有人可以根据这个改进逻辑吗?我尝试实现一些类似于将 id 作为参数传递给函数然后将其作为参数接收并根据它制定逻辑的东西,但我无法做到这一点。如何在React MUI中切换已点击的开关而不是所有开关?

英文:

this is my state in parent component

  const [feedbackType, setFeedbackType] = useState({
    manual: true,
    auto: false,
  });

i am passing this state as a props to child component.
in child component i have this code

const handleFeedbackChange = type =&gt; {
    setFeedbackType(prevState =&gt; ({
      ...prevState,
      manual: type === &#39;manual&#39;,
      auto: type === &#39;auto&#39;,
    }));
  };

    &lt;div&gt;
          &lt;Switch
            checked={feedbackType.manual}
            onChange={() =&gt; handleFeedbackChange(&#39;manual&#39;)}
            name=&quot;manual-feedback&quot;
            inputProps={{ &#39;aria-label&#39;: &#39;Manual feedback&#39; }}
            color=&quot;primary&quot;
          /&gt;
          &lt;label htmlFor=&quot;manual-feedback&quot;&gt;Manual Feedback&lt;/label&gt;

          &lt;Switch
            checked={feedbackType.auto}
            onChange={() =&gt; {handleFeedbackChange(&#39;auto&#39;)}
            name=&quot;auto-feedback&quot;
            inputProps={{ &#39;aria-label&#39;: &#39;Auto feedback&#39; }}
            color=&quot;primary&quot;
          /&gt;
          &lt;label htmlFor=&quot;auto-feedback&quot;&gt;Auto Feedback&lt;/label&gt;
        &lt;/div&gt;

my issue is i am running map on child component so if i have multiple data then there will be multiple switches. so whenever i try to turn on and off first switch then if effect on other switch as well.
can someone improve the logic according to this?
i try to implement something like passing id as a argument to function then receiving it as a parameter and make logic according to it.but i unable to do this.
如何在React MUI中切换已点击的开关而不是所有开关?

答案1

得分: 1

你应该将你的 useState 移到子组件内部,这样当你遍历数据时,React 会为每个渲染的组件创建特定的状态。现在你在所有组件中只使用了一个 useState 钩子:

父组件:

const ParentComponent = () => {
    
    const data = // 你的数据

    return (
        data.map((item, index) => <ChildComponent key={index} item={item} />)
    )
}

你应该像下面的代码示例一样修改 handleFeedbackChange 函数

子组件:

const ChildComponent = ({ item }) => {
    const [state, setState] = useState({
        manual: true,
        auto: false,
    })

    const handleFeedbackChange = type => {
        if(type === 'manual'){
           setState(prevState => ({
             ...prevState,
             manual: true,
           }));
        } else {
           setState(prevState => ({
             ...prevState,
             auto: true,
           }));
        }
    };

    return (
        <Switch
            checked={state.manual}
            onChange={() => handleFeedbackChange('manual')}
        />
        <Switch
            checked={state.auto}
            onChange={() => handleFeedbackChange('auto')}
        />
    )
}
英文:

you should move your useState inside the child component so that when you map throw the data, react would create a specific state for each rendered component, right now you are using one useState hook for all:

parent component:

const ParentComponent = () =&gt; {
    
    const data = // your data

    return (
        data.map((item, index) =&gt; &lt;ChildComponent key={index} item={item} /&gt;)
    )
}

and you should change the handleFeedbackChange function like the code example bellow

child component:

const ChildComponent = ({ item }) =&gt; {
    const [state, setState] = useState({
        manual: true,
        auto: false,
    })

    const handleFeedbackChange = type =&gt; {\
        if(type === &#39;manual&#39;){
           setState(prevState =&gt; ({
             ...prevState,
             manual: true,
           }));
        } else {
           setState(prevState =&gt; ({
             ...prevState,
             auto: true,
           }));
        }
    };

    return (
        &lt;Switch
            checked={state.manual}
            onChange={() =&gt; handleFeedbackChange(&#39;manual&#39;)}
        /&gt;
        &lt;Switch
            checked={state.auto}
            onChange={() =&gt; handleFeedbackChange(&#39;auto&#39;)}
        /&gt;
    )
}

huangapple
  • 本文由 发表于 2023年6月1日 07:08:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76377793.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定