父组件:App组件 子组件:Search组件、List组件
案例需求:文本框中输入关键词,点击搜索按钮后,下方列表展示出搜索结果
实现思路:
子组件Search组件 向父组件App 传递状态(状态包括:是否为第一次打开页面isFirst、是否处于加载中isLoading、搜索出来的列表结果users、请求相关的错误信息err) 解决方案:想要实现子向父传递状态,可以采取父向子传递一个方法,然后子中通过this.props.updateAppState({状态名: “状态值”}) 的方式来实现子组件List 拿到父组件App 中的状态,通过this.props.状态名 App组件:
import React, {Component} from 'react'
import Search from "./components/Search";
import List from "./components/List";
import './App.css';
export default class App extends Component {
state = {
users: [],
isFirst: true,
isLoading: false,
err: ''
}
updateAppState = (stateObj) => {
this.setState(stateObj)
}
render() {
return (
<div className="container">
<Search updateAppState={this.updateAppState} />
<List {...this.state} />
</div>
)
}
}
Search组件:
import React, {Component} from 'react';
import axios from "axios";
class Search extends Component {
search = () => {
const {keyWordElement: {value: keyword}} = this
this.props.updateAppState({isFirst: false, isLoading: true})
axios.get(`https://api.github.com/search/users?q=${keyword}`).then((response) => {
this.props.updateAppState({isLoading: false, users: response.data.items})
},(error) => {
this.props.updateAppState({isLoading: false, err: error.message})
})
}
render() {
return (
<section className="jumbotron" style={{textAlign: "center"}}>
<h3 className="jumbotron-heading">搜索github用户</h3>
<div>
<input ref={c => this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/>
<button onClick={this.search}>搜索</button>
</div>
</section>
);
}
}
export default Search;
List组件:
import React, {Component} from 'react';
import './index.css'
class List extends Component {
render() {
const {users, isFirst, isLoading, err} = this.props
return (
<div className="row">
{
isFirst ? <h2>欢迎使用,输入关键字,随后点击搜索</h2> :
isLoading ? <h2>Loading...</h2> :
err ? <h2 style={{color: 'red'}}>{err}</h2> :
users.map((userObj) => {
return (
<div className="card" key={userObj.id}>
<a href={userObj.html_url} rel="noreferrer" target="_blank">
<img alt="avatar" src={userObj.avatar_url} style={{width: '100px'}}/>
</a>
<p className="card-text">{userObj.login}</p>
</div>
)
})
}
</div>
);
}
}
export default List;
|