我想创建一个自定义选取器组件,我想在每次状态更改后将数据传递给父级,我尝试在 render 方法中使用 this.props.onChange
并传递我想在父级中使用的状态。当我使用consol.log
时,它会记录我想要的值,但是当我使用 value=> this.setState({value})
我收到此错误:
Unhandled JS Exception: Invariant Violation: Invariant Violation: Maximum update depth exceeded.
这是我的代码:
export default class DatePicker extends React.Component {
state = {
days:31,
month: 1,
day : 1,
year : 9500
};
render() {
const {day, month, year} = this.state
this.props.onChange({day,month, year})
return(
<View style={{flex:1 ,flexDirection:'row'}}>
<Picker
selectedValue={this.state.year}
enabled={false}
style={{height: 10, width: 70}}
onValueChange={(itemValue, itemIndex) =>
this.setState({year: itemValue})
}>
{[...Array(12).keys()].map(i => <Picker.Item label={(i+9500).toString()} value={i+9500} /> )}
</Picker>
<Picker
selectedValue={this.state.text}
enabled={false}
style={{height: 0, width: 70}}
onValueChange={(itemValue, itemIndex) =>
this.setState({text: itemValue, days: itemValue < 6? 31 : 30 })
}>
{date.map(i => <Picker.Item label={i.label} value={i.value} /> )}
</Picker>
<Picker
selectedValue={this.state.day}
enabled={false}
style={{height: 10, width: 70}}
onValueChange={(itemValue, itemIndex) =>
this.setState({day: itemValue})
}>
{[...Array(this.state.days).keys()].map(i => <Picker.Item label={(i+1).toString()} value={i+1} /> )}
</Picker>
</View>
)
}
}
博士
我想创建一个具有 OnChange 道具的组件,例如 <TextInput>
最好的方法是什么?
创建函数,该函数将处理值并将其传递给父级
handleOnChange = value => {
const data = {
...this.state,
...value
}
this.setState(data)
this.props.onChane(data)
}
然后在onValueChange
使用该处理程序而不是this.setState
<Picker
selectedValue={this.state.day}
enabled={false}
style={{height: 10, width: 70}}
onValueChange={(itemValue, itemIndex) =>
this.handleOnChange({day: itemValue})
}>
完整的代码将是这样的
export default class DatePicker extends React.Component {
state = {
days:31,
month: 1,
day : 1,
year : 9500
};
handleOnChange = value => {
const data = {
...this.state,
...value,
}
this.setState(data)
this.props.onChange(data)
}
render() {
const {day, month, year} = this.state
this.props.onChange({day,month, year})
return(
<View style={{flex:1 ,flexDirection:'row'}}>
<Picker
selectedValue={this.state.year}
enabled={false}
style={{height: 10, width: 70}}
onValueChange={(itemValue, itemIndex) =>
this.handleOnChange({year: itemValue})
}>
{[...Array(12).keys()].map(i => <Picker.Item label={(i+9500).toString()} value={i+9500} /> )}
</Picker>
<Picker
selectedValue={this.state.text}
enabled={false}
style={{height: 0, width: 70}}
onValueChange={(itemValue, itemIndex) =>
this.handleOnChange({text: itemValue, days: itemValue < 6? 31 : 30 })
}>
{date.map(i => <Picker.Item label={i.label} value={i.value} /> )}
</Picker>
<Picker
selectedValue={this.state.day}
enabled={false}
style={{height: 10, width: 70}}
onValueChange={(itemValue, itemIndex) =>
this.handleOnChange({day: itemValue})
}>
{[...Array(this.state.days).keys()].map(i => <Picker.Item label={(i+1).toString()} value={i+1} /> )}
</Picker>
</View>
)
}
}
在代码中,在循环中呈现函数调用,因为将数据传递给父级时,父级和子级将重新呈现。 您可以编写一个函数来设置状态并将其传递给父级,并在每个选取器onValueChange
调用它,如下所示:
onChange = (newYear, newMonth, newDay) => {
const {day, month, year} = this.state
if (newYear != '') this.setState({ year: newYear }, ()=>{this.props.onChange({day, month, year})})
if (newMonth != '') this.setState({ month: newMonth }, ()=>{this.props.onChange({day, month, year})})
if (newDay != '') this.setState({ day: newDay }, ()=>{this.props.onChange({day, month, year})})
}
并像这样称呼它:
<Picker
onValueChange={(itemValue, itemIndex) =>
this.onChange(itemValue, '', '')
}>
将状态逻辑保留在父组件中。将这些值作为 props 传递给子组件。下面是一个示例:
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class A extends React.Component {
state = {
a: 0
};
updateState = () => {
console.log("hello");
this.setState({
a: this.state.a + 1
});
};
render() {
return <App val={this.state.a} updateState={this.updateState} />;
}
}
function App(props) {
console.log(props);
return (
<div className="App">
{props.val}
<div>
<button onClick={props.updateState}>Increment</button>
</div>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<A />, rootElement);
工作演示