父组件: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: [], // users初始值为数组isFirst: true, // 是否为第一次打开页面isLoading: false, // 标识是否处于加载中err: '' // 存储请求相关的错误信息}// 更新App的stateupdateAppState = (stateObj) => {this.setState(stateObj)}render() {return (<div className="container"><Search updateAppState={this.updateAppState} /><List {...this.state} /></div>)}
}/*function App() {return (<div><Index /></div>);
}*/
Search组件:
import React, {Component} from 'react';
import axios from "axios";class Search extends Component {search = () => {// 获取用户的输入(连续解构赋值+重命名)const {keyWordElement: {value: keyword}} = this// 发送请求前通知App更新状态this.props.updateAppState({isFirst: false, isLoading: true})// console.log(keyword)// 发送网络请求axios.get(`https://api.github.com/search/users?q=${keyword}`).then((response) => {// console.log('成功了', response.data)// 请求成功后通知App更新状态this.props.updateAppState({isLoading: false, users: response.data.items})},(error) => {// console.log('失败了', 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.propsreturn (<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;