我想创建一个自定义选择器组件,我想在每次状态更改后将数据传递给父级,我尝试在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>
)
}
}
我想创建一个具有<TextInput>
之类的OnChange道具的组件,什么是最好的方法?
答案 0 :(得分:0)
创建函数,该函数将处理这些值并将其传递给父级
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>
)
}
}
答案 1 :(得分:0)
保持父组件中的状态逻辑。将这些值作为道具传递给子组件。 这是一个示例:
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);
答案 2 :(得分:-1)
在您的代码中,渲染函数循环调用,因为当您将数据传递给父对象时,父和子对象将重新渲染。您可以编写一个用于设置状态并将其传递给父级的函数,并在每个选择器的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, '', '')
}>