我有一个组件A(bigger container)
,它调用了另外两个组件B(say a kind of header)
和C (input form)
。现在,鉴于用户在C上的行为,我需要隐藏show header。
我有一个解决方案,其中A将功能作为道具传递给C,C可以调用它并更改A中的状态。此修改后的状态传递给B,后者将更改B中的文本。
最小可行示例:-
A:包含带有focused
的状态,并调用B和C组件
class A extends React.Component {
state = {
focused: true,
}
onFocus = () => {
this.setState({ focused: true });
}
onBlur = () => {
this.setState({ focused: false });
}
render() {
return (
<div>
<C onFocus={ this.onFocus } onBlur={ this.onBlur } focus={ this.state.focused } />
<B focus={ this.state.focused } />
</div>
);
}
}
B:仅根据A的道具显示不同的文本
const B = (props) => (
props.focus ? <div> Focussed </div> : <div> Blurred </div>
);
C:包含输入文本框,该文本框根据用户操作执行A中的功能
class C extends React.Component {
state = {
value: '',
}
handleChange(event) {
this.setState({ value: event.target.value });
}
render() {
return (
<input type="text"
value={ this.state.value }
onChange={ this.handleChange }
onFocus={ this.props.onFocus }
onBlur={ this.props.onBlur }
focus={ this.props.focus }
/>
);
}
}
但是,在我的实际应用程序中,我在A和C之间有多个组件(A调用A1调用A2 ...),为了使这些功能可用,所有中间组件都必须将它们作为道具接收。
是否有一种更整洁的方法来解决此要求,而无需让我的每个中间组件都接收这些道具(只希望进一步通过)?
答案 0 :(得分:1)
我能够举例说明如何使用上下文解决上述问题。在示例A中,在较高级别的组件中设置上下文。
if line:
lines = line.strip()
input(f"Does {lines}?>")
print(eval(lines))
现在,在A之下的任何直接或间接组件都可以读取我们从A传递的值。在我们的情况下,C可以将A的值读取为
const ConveyorBelt = React.createContext();
class A extends React.Component {
state = {
focus: true,
onFocus: () => {
this.setState({ focus: true });
},
onBlur: () => {
this.setState({ focus: false });
},
}
render() {
const { focus } = this.state;
return (
<div>
<ConveyorBelt.Provider value={ this.state }>
<C />
</ConveyorBelt.Provider>
<B focus={ focus } />
</div>
);
}
}
现在,我们可以使用A状态更改B中想要的文本。
const C = () => (
<ConveyorBelt.Consumer>
{ (context) => (
<input
onBlur={ context.onBlur }
onFocus={ context.onFocus }
autoFocus={ context.focus }
/>
) }
</ConveyorBelt.Consumer>
);
A和C之间可以有尽可能多的组件,并且不需要将道具传递给所有组件。只有C才能读取A传递的数据,从而解决了道具钻孔的问题。