我需要帮助解决从深层嵌套的子/孙子中更新父状态的最佳方法。
我正在使用React创建表单构建器,允许用户通过在localeStorage中保存持久状态来创建,预览和导出表单。表单有问题,每个问题都有可能的子问题。
我的想法是在应用层上保持所有问题的状态,分配localStorage.setItem('questions',this.state.questions)
数据结构如下:
[
{ question='question 1',
type='text',
condition=null,
isSub= false,
subQ=[{
question='sub question 1',
...
isSub=true,
subQ=[]
}]
},
{
question='question 1',
...
isSub= false,
subQ=[]
},
question='question 1',
...
isSub= false,
subQ=[]
}
]
我的组件层次结构是App - > QuestionForm - >题。 App保持所有问题的状态,Question管理自己的onChange调用updateInputValue,更新值然后调用绑定到QuestionForm组件的updateParent(key,update)。 QuestionForm然后调用绑定到App的updateQuestions(update)。这适用于最外层的问题。使用对子问题所做的更改来更新App状态的最佳方法是什么?
class Question extends Component{
constructor(props){
super(props)
this.state = {
question: props.question
}
this.updateInputValue = this.updateInputValue.bind(this)
}
.....
updateInputValue(e){
let { name, value } = e.target,
question = {...this.props.question }
if( !name ){
value = e.target.parentElement.getAttribute('name') ||
e.target.getAttribute('name')
name = 'type'
}
question[name] = value
this.setState({question: question})
this.props.updateParent(this.props.id, question)
}
这就是我如何在问题中呈现每个问题的子问题 render()组件
{ question.subQ.map( (q, i) =>
<Question key={i}
question={q}
updateParent={this.props.updateParent} /> ) }
QuestionForm组件中的updateParent函数
updateParent = (key, prop) => {
let questions = {...this.state.questions }
questions[key] = prop
this.props.updateQuestions(questions)
}
最后,App组件
class App extends Component {
constructor(props){
super(props)
this.state = {
questions: sample,
activeItem: 'Create'
}
this.checkStorage = checkStorage
this.addQuestion = addQuestion.bind(this)
this.handleTabClick = this.handleTabClick.bind(this)
this.updateQuestions = this.updateQuestions.bind(this)
}
updateQuestions(update){
this.setState({questions: update})
}
我正在考虑采用自下而上的方法,跟踪parentKeys并爬上树,直到'isSub'=== false。有没有更好的方法来解决这个问题?
答案 0 :(得分:0)
如果App要存储您的问题状态,我认为最简单的方法就是给App一个这样的updateQuestion方法:
updateQuestion(path, value) {
const { questions } = this.state;
_.set(questions, path, value);
this.setState({ questions });
}
在这里,我们使用lodash's set
method来横向数据结构并改变您需要的任何值。现在,我们可以绑定此函数并将其作为每个问题的支柱传递下来,并根据需要传递每个子问题。
然后,在渲染方法中,当您将每个问题映射到数据数组时,动态地为其分配一个path
道具,该道具反映了您在该状态下将要更改的值的位置问题调用updateQuestion。
将App的state.questions(或其中的一部分)传递给每个Question作为prop,你可以避免让它们保持自己的状态,这意味着除非你需要生命周期钩子,你可以把问题变成一个功能组件
老实说,当你发现自己不得不冒泡这样的状态时,是时候问自己,redux是不是可行的方法。如果您之前没有使用它,您将拥有一些初始增长的主电源,但它将为您节省大量精力和不必要的复杂性。