Javascript 在何处调用setState以正确更新道具
这是一个全新的反应,我正在制作一个测验应用程序,我需要做以下几点Javascript 在何处调用setState以正确更新道具,javascript,reactjs,Javascript,Reactjs,这是一个全新的反应,我正在制作一个测验应用程序,我需要做以下几点 从一个包含100个问题的外部JS文件(QuizData对象)创建一个包含40个问题的随机数组。这很好,尽管React不是香草JS,但我想知道应该将它们存储在哪里,或者是否应该声明一个如下所示的函数 然后我需要调用setState({questions:questionSet}),将这些新问题分配给我的状态 我需要在我的问题组件中使用它,因为questions[QNum]未定义,所以它当前抛出一个错误 loadQuestions=(
中使用它,因为questions[QNum]
未定义,所以它当前抛出一个错误loadQuestions=()=>{
设arr=[];
让问题集=[];
而(平均长度<40){
var r=Math.floor(Math.random()*100)+1;
if(arr.indexOf(r)==-1)arr.push(r);
}
arr.sort((a,b)=>a-b.forEach((i)=>questionSet.push(QuizData[i-1]);
这是我的国家({
问题:问题集,
});
};
…我的问题似乎来自React的协调过程,setState被异步调用。在setState完成之前调用render函数
我应该在哪里调用setState来加载这些问题?我曾考虑在componentWillmount()中执行此操作,但这已被否决,我尝试在setState中使用回调,但没有成功。只是在寻找处理这类事情的最佳实践
谢谢如果您已经需要(静态)数据,那么最好在构造函数中指定状态
constructor(props) {
super(props);
// Set the questionSet
this.state = { questions: questionSet };
}
您应该调用
componentDidMount
side中的loadQuestions
函数
class App extends Component {
constructor(props){
super(props);
this.state = {questions : [] , ... };
}
componentDidMount(){
this.loadQuestions();
}
...
}
在渲染方法中,在渲染组件之前
检查它是否未定义
render() {
...
return (
questions[QNum] ? <Question data={questions[QNum]} /> : <h1>Loading Questions...</h1>
)
}
render(){
...
返回(
问题[QNum]?:正在加载问题。。。
)
}
我建议您将问题存储在状态中。然后将问题映射到问题
组件列表并呈现。像这样:
class Quiz extends React.Component
{
constructor(props) {
super(props);
this.state = {
questions: [],
}
this.loadQuestions = this.loadQuestions.bind(this);
}
loadQuestions() {
let arr = [];
let questionSet = [];
while (arr.length < 40) {
var r = Math.floor(Math.random() * 100) + 1;
if (arr.indexOf(r) === -1) arr.push(r);
}
arr.sort((a, b) => a - b).forEach((i) => questionSet.push(QuizData[i - 1]));
this.setState({
questions: questionSet,
});
}
componentDidMount() {
this.loadQuestions();
}
render() {
let questions = [];
this.state.forEach( question => {
questions.push( <Question key={question.ID} data={question} /> );
})
return (
<div>{questions}</div>
)
}
}
类测试扩展了React.Component
{
建造师(道具){
超级(道具);
此.state={
问题:[],
}
this.loadQuestions=this.loadQuestions.bind(this);
}
加载问题(){
设arr=[];
让问题集=[];
而(平均长度<40){
var r=Math.floor(Math.random()*100)+1;
if(arr.indexOf(r)==-1)arr.push(r);
}
arr.sort((a,b)=>a-b.forEach((i)=>questionSet.push(QuizData[i-1]);
这是我的国家({
问题:问题集,
});
}
componentDidMount(){
这是loadQuestions();
}
render(){
让问题=[];
this.state.forEach(问题=>{
问题。推送();
})
返回(
{问题}
)
}
}
使用功能设置状态
可以解决您的问题,这也是推荐的做法。但是你说,你已经试过了,但没有成功。你能分享问题的代码沙盒吗?假设
是定义了loadQuestions的同一组件的渲染函数的一部分,我认为你需要为
组件指定一个键,以便在设置状态后重新渲染。这里的QNum
是什么,你如何调用
?发布所有相关代码。看起来QuizData
是静态的。如果是这样,我建议将组件外部的所有随机生成内容(与组件无关)提取到一个常规函数中,然后使用下面的答案将其设置为组件构造函数中的状态this.state={question:generateRandomQuestions();}
@palaѕñQNum
是在我的状态中定义的,我随后对其进行了解构。它将是一个介于1和40之间的整数,当用户循环通过测验时,它将被用来定义他们在哪个问题上。+1到你的第二个片段,-1到你的第一个片段。如果数据已经在道具中,那么您不需要(也不应该将其置于)状态。新开发人员的常见错误。
class Quiz extends React.Component
{
constructor(props) {
super(props);
this.state = {
questions: [],
}
this.loadQuestions = this.loadQuestions.bind(this);
}
loadQuestions() {
let arr = [];
let questionSet = [];
while (arr.length < 40) {
var r = Math.floor(Math.random() * 100) + 1;
if (arr.indexOf(r) === -1) arr.push(r);
}
arr.sort((a, b) => a - b).forEach((i) => questionSet.push(QuizData[i - 1]));
this.setState({
questions: questionSet,
});
}
componentDidMount() {
this.loadQuestions();
}
render() {
let questions = [];
this.state.forEach( question => {
questions.push( <Question key={question.ID} data={question} /> );
})
return (
<div>{questions}</div>
)
}
}