将React-Redux useSelector Hook传递为道具

时间:2020-10-31 20:04:02

标签: javascript reactjs redux react-redux

先驱:我对Redux还是很陌生,但是我对编码足够了解,因此我知道以下解决方案并不理想。尽管它可以工作,但是我对使用eval()并将钩子作为字符串传递确实很。我正在寻找是否有更好的方法可以做到这一点,或者React-Redux是否具有针对我想要实现的内置功能。<​​/ p>

场景:下面代码中的所有ChildComponents都是通用组件(下拉列表等),不应包含将它们链接到特定项目的代码。我试图使它们尽可能通用。但是,当checkBox1触发调度以更改商店中的Item1时,我只希望重新渲染预期的Dropdown(dropdown2),而不是整个ParentComponent(并扩展所有子代)。我还希望dropdown2每次在商店中更改Item1时都更新其选项。我认为可以这样做而无需重新渲染整个ParentComponent的唯一方法是在子级中部署useSelector钩子。我不想在子级中明确声明该钩子,因为这违反了抽象,迫使我将变通方法代码放入通用的Dropdown组件中。

侧面说明:我已经考虑过一些如何在Parent中声明useSelector并防止其强制重新渲染的方法,但是propup在dropdown2上仍然必须更改,这仍将迫使Parent重新渲染以反映dropdown2的新道具。

const ParentComponent = () => {

  let passSelector = "selector(state => state.Item1 ? state.Item2.concat(state.Item3) : state.Item2)";

  let dropdown1 = <Dropdown input={[thing1, thing2]} />;
  let dropdown2 = <Dropdown input={passSelector} />
  let checkbox1 = <Checkbox onClick={() => dispatch(toggleItem1)} />;

  let menu1 = [dropdown1];
  let menu2 = [dropdown2, checkbox1];

  return (
    <div>
      <Checkbox1 onClick={doThing} />
      <Switch onSwitch={switchyThing} />
      {mode &&
         menu1
      }
      {!mode &&
         menu2
      }
    <div/>
  );
}

const Dropdown = ({input}) => {
  const selector = useSelector; // Grabbed from the import statements to force importation.
  const options = (typeof input === 'string') ? eval(input) : input;

  ... some other code ...

  return (
    {options && options.map(option => {
      ...do thing with option...
    }
  );
}   

1 个答案:

答案 0 :(得分:0)

您可以只将要用作选择器的功能从父级传递到子级,而不是字符串。像这样吗?

const ParentComponent = () => {

  const selector = state => state.Item1 ? [...state.Item2, ...state.Item3] : state.Item2;

  return (
    <div>
      <Dropdown selector={selector} />
    <div/>
  );
}

const Dropdown = ({selector}) => {
  const options = useSelector(selector);

  //... some other code ...

  return (
    {options && options.map(option => {
      //...do thing with option...
    }
  );
}