我无法从 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
);
我正在使用 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>
);
}
情况:
我或多或少地尝试过他们如何解释
此外,我的目标是在父级中使用此组件,或多或少是这样的: **父组件:**
<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
);