我无法从 React Typescript 组件上的 onChange 获得结果

I can't get results from onChange on a React Typescript component

我正在使用 the React Color lib 在我的应用程序中创建自定义组件。我的子组件由 React Colors 的两个组件组成:CirclePicker 和 ChromePicker。两者共享 colorPicker 状态变量作为值。所以,如果一个人改变了他的价值,另一个人也会改变。

正如您在我的子组件上看到的那样,我放置了一个共享相同 colorPicker 值的不可见输入(我不知道这样做是否正确) .我的目标是:当输入发生变化时,我可以做一些事情,例如:alert('COLOR CHANGED')(这是我在 handleOnChange 中的代码 函数)

子组件:

import React from 'react';
import { CirclePicker, ChromePicker } from 'react-color';
import { Icon } from './../Icon/Icon';
import './color-picker.scss';

export interface ColorPickerProps {
  onChange: (value: string) => void;
}

export function ColorPicker(props: ColorPickerProps) {
  const [colorPicker, showColorPicker] = React.useState(false);
  const [finalColor, changeColor] = React.useState('#fff');
  function handleOnChange() {
    alert('COLOR CHANGED');
    props.onChange(finalColor);
  }
  return (
    <div className="relative-position">
      <input type="text" value={finalColor} onChange={() => handleOnChange} style={{display: "none"}}/>
      <CirclePicker
        color={finalColor}
        onChangeComplete={colore => changeColor(colore.hex)}
        colors={[
          '#004de8',
          '#2ecc71',
          '#ff9300',
          '#62708b',
          '#ff003a',
          '#20396a'
        ]}
        circleSize={24}
      ></CirclePicker>
      <a
        className="btn-select-color"
        onClick={() => showColorPicker(!colorPicker)}
      >
        <Icon viewIcone="ArrowDropDown" style={{ margin: '5px' }} />
      </a>
      {colorPicker ? (
        <span className="chrome-picker">
          <ChromePicker
            color={finalColor}
            onChangeComplete={colore => changeColor(colore.hex)}
            disableAlpha={true}
          />
        </span>
      ) : (
        ''
      )}
    </div>
  );
}

情况:

我或多或少地尝试过他们如何解释 ,但无论我做什么,handleOnChange 函数都没有被调用,我不能'看不到警报。

此外,我的目标是在父级中使用此组件,或多或少是这样的: **父组件:**

<ColorPicker onChange={e => this.state.color = e} />

所以,通过这种方式,我可以在父状态上选择颜色。

我在 Child 函数中什么也得不到,也没有在父组件上更新状态。

有人可以帮助我吗?我是 React 的新用户:(

useCallback可能是个不错的选择,参考这个QA, and document

import React from "react";
import ReactDOM from "react-dom";
import { CirclePicker, ChromePicker } from "react-color";

import "./styles.css";

function App(props) {
  const [colorPicker, showColorPicker] = React.useState(false);
  const [finalColor, changeColor] = React.useState("#fff");

  const handleColorChange = React.useCallback(console.log("Work via callback"));
  return (
    <div className="relative-position">
      <input value={finalColor} onChange={console.log("Work directly")} />
      <input value={finalColor} onChange={handleColorChange} />
      <CirclePicker
        color={finalColor}
        onChangeComplete={colore => changeColor(colore.hex)}
        colors={[
          "#004de8",
          "#2ecc71",
          "#ff9300",
          "#62708b",
          "#ff003a",
          "#20396a"
        ]}
        circleSize={24}
      />
      {colorPicker ? (
        <span className="chrome-picker">
          <ChromePicker
            color={finalColor}
            onChangeComplete={colore => changeColor(colore.hex)}
            disableAlpha={true}
          />
        </span>
      ) : (
        ""
      )}
      <p>{finalColor}</p>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

说明

输入值与状态相关联。因此,当状态发生变化时,值也会发生变化。但是,输入上没有触发任何事件。您试图在未触发任何事件的输入上使用反应 event handler;意思是 handleOnChange 从未被调用所以 props.onChange 从未被调用...

解决方案

使用useEffect to listen for when the input's value/state value changes. If you use useRef, you can stop your props.onChange from running when the component mounts. Check out the DEMO.

import * as React from "react";
import { FunctionComponent, useState, useEffect, useRef } from "react";
import { render } from "react-dom";
import { CirclePicker, ChromePicker } from "react-color";

const colors = [
  "#004de8",
  "#2ecc71",
  "#ff9300",
  "#62708b",
  "#ff003a",
  "#20396a"
];

export interface ColorPickerProps {
  onChange: (value: string) => void;
}

const ColorPicker: FunctionComponent<ColorPickerProps> = ({ onChange }) => {
  const [colorPicker, showColorPicker] = useState(false);
  const [finalColor, changeColor] = useState("#fff");
  const componentMounted = useRef(true);

  useEffect(() => {
    if (componentMounted.current) {
      componentMounted.current = false;
      console.log(
        "Don't run props.onChange when the component mounts with useRef"
      );
    } else {
      onChange(finalColor);
      alert("finalColor changed via useEffect");
    }
    return () => undefined;
  }, [finalColor]);

  return (
    <div className="relative-position">
      <input type="text" value={finalColor} style={{ display: "none" }} />
      <CirclePicker
        color={finalColor}
        onChangeComplete={colore => changeColor(colore.hex)}
        colors={colors}
        circleSize={24}
      />
      <br />
      <button onClick={() => showColorPicker(!colorPicker)}>click me</button>
      {colorPicker && (
        <span className="chrome-picker">
          <ChromePicker
            color={finalColor}
            onChangeComplete={colore => changeColor(colore.hex)}
            disableAlpha={true}
          />
        </span>
      )}
    </div>
  );
};

const rootElement = document.getElementById("root");
render(
  <ColorPicker
    onChange={() => {
      console.log("onChange");
    }}
  />,
  rootElement
);