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

问题描述 投票:0回答:2

我正在使用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>
  );
}

情况:

我已经或多或少尝试了他们对here的解释,但是无论我做什么,都不会调用handleOnChange函数,而且我也看不到警报。

此外,我的目标是在父级中使用此组件,大致像这样:**父组件:**

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

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

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

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

reactjs typescript onchange
2个回答
1
投票

说明

输入的值链接到状态。因此,当状态更改时,值也会更改。但是,没有事件触发输入。您正在尝试在未触发任何事件的输入上使用react event handler。表示handleOnChange从未被调用,所以props.onChange从未被调用...

解决方案

使用useEffect来侦听输入值/状态值的变化。如果使用useRef,则可以在安装组件时停止运行props.onChange。签出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
);

1
投票

useCallback可能是一个不错的选择,请参考此QAdocument

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);

Edit silly-rgb-lf7k6

© www.soinside.com 2019 - 2024. All rights reserved.