在子组件中使用React钩子

时间:2020-10-24 16:14:15

标签: reactjs react-hooks

我通过在此处传递它来尝试在子组件中使用React钩子的setState方法:

function CompilerOptions({ preset }: CompilerOptionsProps) {
  return (
    <section className="app-grid-item">
      {questions.compilerOptions.map(
        ({
          name,
          description,
          values,
          defaultValue,
          presets,
          linkToReference,
        }) => {
          const [value, setValue] = useState<string | boolean | null>(null);
          const handleValueChange = useCallback(
            (newValue: string) => setValue(newValue),
            []
          );
          return (
            <div key={name} className="section-block input-block">
              <h2 className="block-heading">{name}</h2>
              <p className="block-headline">
                Default: <span className="monospace">{defaultValue}</span>{" "}
                {linkToReference ? (
                  <React.Fragment>
                    &bull;{" "}
                    <a
                      href={"https://www.typescriptlang.org/tsconfig#" + name}
                      target="blank"
                      title="TypeScript reference"
                      className="block-referencelink"
                    >
                      Get the reference
                    </a>
                  </React.Fragment>
                ) : null}
              </p>
              <p
                className="block-paragraph"
                dangerouslySetInnerHTML={{
                  __html: description
                    .replace("%MONOSPACE%", `<span class="monospace">`)
                    .replace("%STOPMONOSPACE%", "</span>"),
                }}
              />
              <button onClick={() => console.log(value)}>get value</button>
              <form className="block-form">
                <div className="block-grid">
                  {values.map((value) => {
                    const key = randomizedValue(value);
                    return (
                      <CompilerOption
                        key={key}
                        keyString={key}
                        presetValue={presets[preset]}
                        value={value}
                        setValue={handleValueChange}
                      />
                    );
                  })}
                </div>
              </form>
            </div>
          );
        }
      )}
    </section>
  );
}

然后在CompilerOption组件中像这样使用它:

function CompilerOption({
  //...
  setValue,
}: CompilerOptionProps) {
  //...
  return (
    <div key={keyString}>
      <input
        type="radio"
        id={keyString}
        value={keyString}
        defaultChecked={isPresetOption}
        onSelect={() => {
          setValue(value);
        }}
      />
      //...
    </div>
  );
}

但是后来,我犯了一个错误,那就是我刚刚违反了《胡克规则》:

Line 33:37:  React Hook "useState" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function  react-hooks/rules-of-hooks

怎么了?我确实在React函数组件中使用了一个钩子。

1 个答案:

答案 0 :(得分:2)

编辑:

使用如下所示的返回地图元素来制作组件。

const Item = ({item}) => {
  // your code
  const [value, setValue] = useState<string | boolean | null>(null);

  return (
    ...
  )
}

const renderItems = useCallback(() => {
  return questions.compilerOptions.map((item, idx) => {
     return <Item item={item} key={idx} />
  })
}, [questions.compilerOptions])