reactjs - 在 reactjs 中使用状态和映射时出错
问题描述
我是新来的反应。我在搜索中获取 github 用户信息。我无法在我的子组件中获取数据。这是我下面的代码。什么问题,我不能使用 this.state.userList.map
class SearchHeader extends Component {
constructor(props) {
super(props);
this.state = {
errorMessage: '',
userList: [],
isOpen: false,
userName:''
};
this.toggle = this.toggle.bind(this);
this.getUsers = this.getUsers.bind(this);
}
toggle() {
this.setState({
isOpen: !this.state.isOpen
});
}
// componentWillMount(){
// this.getUsers();
// }
getUsers(e) {
console.log('get users called='+e.target.value);
fetch('https://api.github.com/search/users?q='+ e.target.value)
.then(res => res.json())
.then(
userList =>{
this.setState({userList: userList})
console.log(userList);
}
);
}
render() {
return (
<div>
<nav className="navbar navbar-expand-lg navbar-light bg-primary navbar-inner">
<div className="collapse navbar-collapse navbar-inner navb" >
<ul className="navbar-nav bg-light mr-auto">
<li className="nav-item dropdown">
<a className="nav-link dropdown-toggle auto" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Sort
</a>
<div className="dropdown-menu" aria-labelledby="navbarDropdown">
<a className="dropdown-item" href="#">Sort by Name (ascending)</a>
<a className="dropdown-item" href="#">Sort by Name (descending)</a>
<div className="dropdown-divider"></div>
<a className="dropdown-item" href="#">Sort by Rank (ascending)</a>
<a className="dropdown-item" href="#">Sort by Rank (descending)</a>
</div>
</li>
</ul>
<form className="form-inline my-2 my-lg-0 auto" onSubmit={this.getUsers}>
<div className="form-group">
<input className="form-control mr-sm-2" type="Search" placeholder="Search"
aria-label="Search"
id="userName"
onKeyUp={this.getUsers} >
</input>
</div>
</form>
</div>
</nav>
<div >
<UserList userList={this.state.userList}/>
</div>
</div>
);
}
}
export default SearchHeader;
这是我从父组件获取数据的下面的子组件 这是我从父组件获取数据的下面的子组件
class UserList extends Component {
constructor(props) {
super(props)
this.state ={
users:this.props.userList
}
}
render() {
return (
<div className="container-fluid">
<br />
{
this.state.users.map((user)=>
<div className="jumbotron container">
{user.login}
</div>
)
}
</div>
);
}
}
export default UserList;
解决方案
您的组件中有几个问题:
- 不要将父母的状态复制到儿童状态:
users:this.props.userList
. 直接使用this.props
,React 会知道它必须重新渲染孩子 - 不要依赖当前状态来设置新状态。使用函数 with
prevState
而不是isOpen: !this.state.isOpen
。 - 在将事件值传递给之前复制
setState
它const {value} = e.target;
- 为列表中的每个用户分配唯一键(不是索引!),否则它不会在列表更新时正确重新呈现
所以你的代码看起来像这样:
class SearchHeader extends Component {
constructor(props) {
super(props);
this.state = {
errorMessage: '',
userList: [],
isOpen: false,
userName:''
};
}
toggle = () => {
this.setState( (prevState) => ({
isOpen: !prevState.isOpen
}));
}
getUsers = (e) => {
const {value} = e.target;
console.log('get users called='+value);
fetch('https://api.github.com/search/users?q='+ value)
...
}
}
和:
class UserList extends Component {
// Use default constructor
render() {
const users = this.props.userList.map( (user) => (
<div className="jumbotron container" key={user.login}>
{user.login}
</div>
));
return (
<div className="container-fluid">
<br />
{users}
</div>
);
}
}
推荐阅读
- colors - 如何为某些补丁颜色设置“吸引力”值或级别 Netlogo
- python-3.x - 无法验证并插入 mongo DB。pymongo-蟒蛇
- java - 使用比较器接口对 ArrayList 进行排序
- javascript - ReactJs setState 不适用于 this 关键字
- oracle - 在apex oracle的过程中检查匹配的数字
- javascript - 开玩笑地为 addEventListener 编写单元测试时遇到麻烦
- java - java.lang.NoClassDefFoundError: org/hamcrest/Matchers
- azure - 将默认 CosmosSerializationOptions 更改为 camelCase 会导致 CosmosDB SDK V4 中出现异常
- laravel - 我正在使用 laravel 6 从 mailgun 发送邮件。实际上邮件已送达,但垃圾邮件不在收件箱中
- apache-flink - Apache Flink - 数据集 api - 侧输出