我正在使用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的新用户:(
输入的值链接到状态。因此,当状态更改时,值也会更改。但是,没有事件触发输入。您正在尝试在未触发任何事件的输入上使用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
);
useCallback
可能是一个不错的选择,请参考此QA和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);