我创建了以下React组件。它使用输入框来接受用户对谜语的回答。用户的输入与所需答案匹配后,输入框将变为只读(使用它们的方式有些奇怪)。它还有一个“ isHidden”道具来确定是否渲染了谜语。
class Riddle extends React.Component {
constructor(props) {
super(props);
this.answer = props.answer.toUpperCase();
this.state = {
text: "",
isAnswered: false
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
let userInput = event.target.value.toUpperCase();
if (userInput == this.answer) {
this.setState({
text: userInput,
isAnswered: true
});
} else {
this.setState({
text: userInput,
isAnswered: false
});
}
}
render() {
if (this.props.isHidden) {
return <div></div>;
} else {
return (
<div>
<p>{this.props.prompt}</p>
<input type="text" value={this.state.text}
readOnly={this.state.isAnswered}></input>
</div>
);
}
}
}
在实践中:
function App() {
return (
<div>
<Riddle prompt='The first three letters in the alphabet.' answer="abc" isHidden="false"/>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
我想做的是按顺序排列一堆这些谜语,但是只有在解决前一个谜语时才能看到这些谜语。问题在于我不知道如何导致可见性更新发生。
我已经阅读了有关将状态从子级提升到父级组件的信息,并且尝试查看是否可以创建一个RiddleSequence
作为其子级的Riddle
组件,并使用{{1 }}管理可见性。我的问题是,目前RiddleSequence
的状态是否得到解决是其一部分,并且我不知道Riddle
如何读取该信息,因为子状态应该保持隐藏。这似乎是封装RiddleSequence
功能的一种合理方法,但是考虑到我的目标,也许我错了。
我还考虑过让Riddle
成为他们赖以生存的其他谜语的孩子,因为我可以将状态/道具传递给孩子:
Riddle
但是,如果我有一个带有100个谜语的应用,这似乎太荒谬了。这也降低了灵活性,可用于更多扩展的功能集(例如使一个谜语取决于一组3个谜语)。
如何使<Riddle prompt="first riddle"...>
<Riddle prompt="depends on first riddle"...>
<Riddle prompt="depends on second riddle"...>
</Riddle>
</Riddle>
</Riddle>
组件的可见性取决于其他谜语的状态?
答案 0 :(得分:1)
一个简单的解决方案是拥有您所说的容器组件:
class Riddle extends Component {
constructor(props) {
this.state = {
text: ''
}
this.answer = props.answer.toUpperCase()
}
handleChange = event => {
const userInput = event.target.value.toUpperCase()
const callback = userInput == this.answer ? this.props.onSolved : undefined
this.setState({ text: userInput }, callback)
}
render() {
const { text, isAnswered } = this.state
const { prompt } = this.props
if (this.props.isHidden) {
return null
}
return (
<div>
<p>{prompt}</p>
<input type="text" value={text} readOnly={isAnswered}></input>
</div>
)
}
}
并且容器应具有这样的可见性:
class RiddleSequence extends Component {
state = {}
riddles = [
{
id: 1,
prompt: 'The first three letters in the alphabet.',
answer: 'abc',
prev: null
},
{
id: 2,
prompt: 'The last three letters in the alphabet.',
answer: 'xyz',
prev: 1
}
]
render() {
return (
<div>
{this.riddles.map(r => {
const { id, prev } = r
const visible = !prev || this.state[prev]
return (
<Riddle
key={id}
isHidden={!visible}
onSolved={() => this.setState({ [r.id]: true })}
{...r}
/>
)
})}
</div>
)
}
}