所以这可能有点令人困惑所以我会尽力简化它。
我的状态包含父组件App.js
中的对象数组。这是一个对象的例子。
{
category: "sample category",
API: "API URL",
active: function()
}
在我的子组件Category.js
中,我通过道具传递了该数组。子项呈现ul
,然后映射数组以为每个类别创建li
。每个列表项都应该有一个onClick事件,该事件触发对象中的关联active: function()
。
由于某种原因,这不起作用。如果我运行一个函数是简单console.log("success")
的测试,那就没问题了。所以列表项是通过我的道具获取功能并运行它。
这让我相信这就是我正在运行的实际功能。我正在尝试运行的功能是这个(位于App.js
)
function() {
this.setState({categoryActive: "https://opentdb.com/api.php?amount=20&category=11"});
this.setState({showQuestions: true});
}
正在设置的状态位于App.js
,该函数也位于App.js
中,但正由Category.js
中的列表项通过道具运行。这是我的问题吗?我可以不通过子组件中的函数运行来调整App.js
的状态吗?
编辑:这里有更多的代码可以帮助找出解决方案。
实际错误:未捕获的TypeError:无法读取未定义的属性'setState' 在catMovies(App.js:71)
App.js:71是this.setState({categoryActive: "https://opentdb.com/api.php?amount=20&category=11"});
函数的catMovies()
。
我的App.js
构造函数
constructor(props) {
super(props);
this.state = {
showCategories: false,
showQuestions: false,
isQuestionLoaded: false,
categories: [{
category: "movies",
API: "https://opentdb.com/api.php?amount=10&category=11",
active: this.catMovies
}, {
category: "sports",
API: "https://opentdb.com/api.php?amount=10&category=21",
active: this.catSports
}, {
category: "books",
API: "https://opentdb.com/api.php?amount=10&category=10",
active: this.catBooks
}, {
category: "videogames",
API: "https://opentdb.com/api.php?amount=10&category=15",
active: this.catVideogames
}, {
category: "general",
API: "https://opentdb.com/api.php?amount=10&category=9",
active: this.catGeneral
}, {
category: "everything",
API: "https://opentdb.com/api.php?amount=10",
active: this.catEverything
}],
categoryActive: "",
questionNumber: 0,
questionTotal: null,
correct: [],
score: 0,
showFinal: false,
testState: "test"
};
this.showCategories = this.showCategories.bind(this);
this.showQuestions = this.showQuestions.bind(this);
this.catMovies = this.catMovies.bind(this);
}
以下是App.js
中的实际功能:
catMovies() {
this.setState({categoryActive: "https://opentdb.com/api.php?amount=20&category=11"});
this.setState({showQuestions: true});
}
以下是App.js
的回复,称为儿童权益:
<Categories categoryList={ this.state.categories } onClick={ this.catMovies } />
最后,这是子组件中使用所有这些的映射:
const categoryListItems = this.props.categoryList.map(cat =>
<a href="#questionsContainer" key={cat.category + "link"}>
<li onClick={cat.active} key={cat.category}>
{cat.category}
</li>
</a>
);
答案 0 :(得分:3)
你的问题在于处理程序的绑定 而不是像在构造函数中那样覆盖处理程序,而应该直接在状态初始化中执行:
this.state = {
showCategories: false,
showQuestions: false,
isQuestionLoaded: false,
categories: [{
category: "movies",
API: "https://opentdb.com/api.php?amount=10&category=11",
active: this.catMovies.bind(this) // <-- you need to bind here
},
//...
这是一个包含两种模式的运行示例,请注意turnOff
处理程序将如何抛出相同的错误:
const LightBall = ({ on }) => {
return (
<div>{`The light is ${on ? 'On' : 'Off'}`}</div>
);
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
lightOn: false,
toggle: this.toggleLight.bind(this), // this will work
turnOff: this.turnOff // this will not work
};
this.turnOff = this.turnOff.bind(this);
}
toggleLight(){this.setState({ lightOn: !this.state.lightOn })};
turnOff() { this.setState({ lightOn: false }) };
render() {
const { lightOn, toggle, turnOff } = this.state;
return (
<div>
<button onClick={toggle}>Toggle Light</button>
<button onClick={turnOff}>Turn Off</button>
<LightBall on={lightOn} />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
&#13;
答案 1 :(得分:0)
问题可能是由于这个功能
function() {
this.setState({categoryActive: "https://opentdb.com/api.php?amount=20&category=11"});
this.setState({showQuestions: true});
}
this
被称为调用函数的类。
您可以通过使用App
将数组传递给子项之前将函数绑定到bind()
组件来解决此问题(请参阅此处https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)
或者您可以使用箭头函数,如果您在App
组件中定义它以自动将其范围绑定到该组件,那么
{
category: "sample category",
API: "API URL",
active: () => {
this.setState({categoryActive: "https://opentdb.com/api.php?amount=20&category=11"});
this.setState({showQuestions: true});
}
}
在此处详细了解箭头功能https://babeljs.io/learn-es2015/#arrows-and-lexical-this