github搜索案例(axios、pubsub、fetch)

2.github搜索案例(axios、pubsub、fetch)

目录结构

实现效果:

2.1使用axios发送请求

App.jsx

class App extends Component {

    state = {
        users: [], // 初始化状态,users初始值为数组
        isFirst: true, // 是否为第一次打开页面
        isLoading: false, //标识是否处于加载中
        err: '', //存取请求相关的信息
    }

    // 更新APP的state
    updateAppState = (stateObj) => {
        console.log(stateObj)
        this.setState(stateObj)
    }


    render() {
        return (
            <div className="container">
                <Search updateAppState={this.updateAppState} />
                <List {...this.state}/>
            </div>

        );
    }
}

Search.jsx

class Search extends Component {

    componentDidMount() {
        let obj = {a:{b:{c:1}}}
        // 连续解构赋值
        const {a:{b:{c}}} = obj
        console.log(c)

        // 连续解构赋值并重命名
        let obj2 = {a:{b:2}}
        const {a:{b:data}} = obj2
        console.log(data)
    }

    search = () => {
        // 获取用户的输入
        // 连续解构赋值+重命名
        const {keyWordElement:{value:keyWord}} = this
        console.log(keyWord)
        // 发送请求前通知APP更新状态
        this.props.updateAppState({isFirst:false, isLoading:true})
        // 发送网络请求
        axios.get(`https://api.github.com/search/users?q=${keyWord}`).then(
                res=>{
                    // 请求成功通知APP更新状态
                    this.props.updateAppState({users: res.data.items, isLoading:false})
                },
                err=>{
                   // 请求失败通知APP更新状态
                    this.props.updateAppState({err: err.message, isLoading:false})
                })
    }

    render() {
        return (
            <section className="jumbotron">
                    <h3 className="jumbotron-heading">搜索GitHub用户</h3>
                    <div>
                        <input ref={c=>this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/>&nbsp;
                        <button onClick={this.search}>搜索</button>
                    </div>
                </section>
        );
    }
}

List.jsx

class List extends Component {
    render() {
        const {users, isFirst, isLoading, err} = this.props
        return (
            <div className="row">
                {/*多重三元表达式*/}
                {isFirst ? <h2>Welcome to losantu</h2> :
                    isLoading ? <h2>Loading...</h2> :
                        err ? <h2>{err}</h2> :
                            users.map(user => {
                                return (
                                    <div className="card" key={user.id}>
                                        <a href={user.html_url} target="_blank" rel="noreferrer">
                                            <img alt='head_portrait' src={user.avatar_url}
                                                 style={{ "100px"}}/>
                                        </a>
                                        <p className="card-text">{user.login}</p>
                                    </div>
                                )
                            })
                }
            </div>
        );
    }
}

2.2使用pubsub发布订阅更新。

npm install pubsub-js --save

不需要在父组件App.jsx上写updateAppState方法了

Search.jsx

class Search extends Component {

    componentDidMount() {
        let obj = {a:{b:{c:1}}}
        // 连续解构赋值
        const {a:{b:{c}}} = obj
        console.log(c)

        // 连续解构赋值并重命名
        let obj2 = {a:{b:2}}
        const {a:{b:data}} = obj2
        console.log(data)
    }

    search = () => {

        // PubSub.publish('state',{name:'tom', age:18})

        // 获取用户的输入
        // 连续解构赋值+重命名
        const {keyWordElement:{value:keyWord}} = this
        console.log(keyWord)
        // 发送请求前通知List更新状态
        // 发布一条主题为state的数据
        PubSub.publish('state',{isFirst:false, isLoading:true})
        axios.get(`https://api.github.com/search/users?q=${keyWord}`).then(
                res=>{
                    // 请求成功通知List更新状态
                    PubSub.publish('state',{users: res.data.items, isLoading:false})
                },
                err=>{
                   // 请求失败通知List更新状态
                    PubSub.publish('state',{err: err.message, isLoading:false})
                })
    }

    render() {
        return (
            <section className="jumbotron">
                    <h3 className="jumbotron-heading">搜索GitHub用户</h3>
                    <div>
                        <input ref={c=>this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/>&nbsp;
                        <button onClick={this.search}>搜索</button>
                    </div>
                </section>
        );
    }
}

List.jsx

class List extends Component {

    state = {
        users: [], // 初始化状态,users初始值为数组
        isFirst: true, // 是否为第一次打开页面
        isLoading: false, //标识是否处于加载中
        err: '', //存取请求相关的信息
    }

    componentDidMount() {
       // 订阅state主题,获取发布该主题的数据
       this.token = PubSub.subscribe('state', (msg,data)=>{
           console.log(data)
           this.setState(data)
       })
    }

    componentWillUnmount() {
        PubSub.unsubscribe(this.token)
    }

    render() {
        const {users, isFirst, isLoading, err} = this.state
        return (
            <div className="row">
                {  isFirst ? <h2>Welcome to losantu</h2> :
                    isLoading ? <h2>Loading...</h2> :
                        err ? <h2>{err}</h2> :
                            users.map(user => {
                        return (
                            <div className="card" key={user.id}>
                                <a href={user.html_url} target="_blank" rel="noreferrer">
                                    <img alt='head_portrait' src={user.avatar_url}
                                         style={{ "100px"}}/>
                                </a>
                                <p className="card-text">{user.login}</p>
                            </div>
                        )
                    })
                }
            </div>
        );
    }
}

2.3使用fetch发送请求

修改search方法

    search = async () => {

        // PubSub.publish('state',{name:'tom', age:18})

        // 获取用户的输入
        // 连续解构赋值+重命名
        const {keyWordElement:{value:keyWord}} = this
        console.log(keyWord)
        // 发送请求前通知List更新状态
        PubSub.publish('state',{isFirst:false, isLoading:true})
        //#region 发送网络请求---使用axios发送
        // axios.get(`https://api.github.com/search/users?q=${keyWord}`).then(
        //         res=>{
        //             // 请求成功通知List更新状态
        //             PubSub.publish('state',{users: res.data.items, isLoading:false})
        //         },
        //         err=>{
        //            // 请求失败通知List更新状态
        //             PubSub.publish('state',{err: err.message, isLoading:false})
        //         })
        //#endregion

        //#region 发送网络请求---使用fetch发送(未优化版本)
        // fetch(`https://api.github.com/search/users?q=${keyWord}`).then(
        //     res=>{
        //         console.log('联系服务器成功了', res)
        //         return res.json()
        //     },
        //     err=>{
        //         console.log('联系服务器失败了', err)
        //         return new Promise(()=>{})
        //     },
        // ).then(
        //     res=>{console.log('获取数据成功了', res)},
        //     err=>{console.log('获取数据失败了', err)},
        // )
        //#endregion

        //#region 发送网络请求---使用fetch发送(优化版本)
        // fetch(`https://api.github.com/search/users?q=${keyWord}`).then(
        //     res=>{
        //         console.log('联系服务器成功了', res)
        //         return res.json()
        //     },
        // ).then(
        //     res=>{console.log('获取数据成功了', res)},
        // ).catch(
        //     err=>{console.log('请求错误', err)}
        // )
        //#endregion

        //#region 发送网络请求---使用fetch发送(await try catch优化版本)
        try {
            const res = await fetch(`https://api.github.com/search/users?q=${keyWord}`)
            const data = await res.json()
            PubSub.publish('state',{users: data.items, isLoading:false})
        }  catch (err) {
             console.log('出错了', err)
            PubSub.publish('state',{err: err, isLoading:false})
        }

        //#endregion

    }

原文地址:https://www.cnblogs.com/guapitomjoy/p/15223720.html