我有以下反应原生代码。我的想法是,我希望移动所有常用功能(在下面的例子中,它是保存按钮和相应的功能到父类)。
export default class DocumentScreen extends Component {
save() {
console.log(this.state);
}
render() {
return (
<View>
{this.props.children}
<View>
<Button onClick={this.save.bind(this)}/>
</View>
<View>
);
}
}
子文档负责实际定义屏幕上显示的字段,例如
export default (props) => (
<DocumentScreen {...props}>
<View>
<TextInput onChangeText={(val) => this.setState({val})}/>
<View>
</DocumentScreen>
);
不幸的是,this.setState
调用文本输入字段的更改不会改变父对象的状态,所以当我触发save
中定义的DocumentScreen
函数调用时,它& #39; s状态为空。
我最好的方式是在子组件中公开父{q} setState
函数?
谢谢。
答案 0 :(得分:1)
这是React的常见用例。解决方案应该在父组件内声明处理函数,然后将其传递给子组件。您需要注意函数的上下文,以便this
正确指向父函数,可以通过在javascript中使用bind
函数或使用箭头函数声明事件处理程序来完成。一个例子如下:
export default class DocumentScreen extends Component {
changeHandler = (val) => {
this.setState({ val });
}
// Binding function inside JSX should be avoid
render() {
return (
<View>
{this.props.children}
<ChildComponent onChange={this.changeHandler} />
</View>
)
}
}
// Child Component
export default (props) => (
<DocumentScreen>
<View>
<TextInput onChangeText={props.onChange}/>
</View>
</DocumentScreen>
);
答案 1 :(得分:1)
因为我看到你使用HOC作为答案,我认为可以使用renderProps。这比使用HOC更好。你获得了更多的自由,而且你也没有道具命名问题。一个好的视频,你可以看到它的强度与HOC https://youtu.be/BcVAq3YFiuc
小例子
class DocumentScreen extends Component {
state = {
value: ''
}
save() {
console.log(this.state);
}
handleChange = value => {
this.setState({ value })
}
render() {
return (
<View>
{this.props.children({ handleChange: this.handleChange })}
<View>
<Button onClick={this.save.bind(this)}/>
</View>
</View>
);
}
}
const Input = (props) => (
<DocumentScreen {...props}>
{({ handleChange }) => (
<View>
<TextInput onChangeText={handleChange}/>
<View>
)}
</DocumentScreen>
);
答案 2 :(得分:0)
所以,我最终做的是将我的父组件包装在HOC函数中,如下所示:
export function wrapper(DocumentComponent) {
return class extends Component {
changeHandler = (val) => {
this.setState({ val });
}
save() {
console.log(this.state);
}
render() {
return (
<View>
<DocumentComponent onChange={this.changeHanlder}/>
<View>
<Button onClick={this.save.bind(this)}/>
</View>
<View>
);
}
};
}
然后我使用包装函数将子句传递给父项(父项现在可以将道具传递回子项)。
export default wrapper(
(props) => (
<View>
<TextInput onChangeText={props.onChange}/>
</View>
)
)
虽然在这里发生了一些循环引用......