Github搜索案例
今天的内容是这个案例的实现,以及其中涉及到的内容,需要全部掌握,比如ref,受控组件,props在组件之中的传递,以及Pubsub包的使用这些前端React框架有关的内容。现在进入正题
1.github搜索案例(axios)
我们直接导入静态页面,这个方面html,css引入到组件拆分,我们就不说了,直接跳过。我们分为3个组件,首先App组件,Search组件以及List展示组件。
现在我们分好了组件也引入了静态html以及css之后页面是这个效果
图片我们暂时随便的用一种,现在我们首先要做的就是,我们要在Search组件中,实现一个效果,就是我们在点击Search按钮的时候,我们能够去发送一个请求给服务器对应的端口上的服务,然后服务给我们一些我们搜索相关的数据返回,然后我们把这些数据想办法给List组件,然后让List组件展示出我们搜索出来的内容。
首先添加一个点击事件,当按钮被点击的时候,我们触发函数,那么在这个函数中,我们发送请求之前需要获取input输入框的value值,因为我们搜索的关键字是我们自己输入的,但是现在我们发生事件的元素并不是我们需要获取value的元素,这时候我们就有两种办法,在按钮元素点击事件的时候拿到别的元素的value。
1.ref
我们直接给input设定ref ={event=>{this.keyWord = event}}相当于在ref中搞了一个箭头函数,函数定义了我们Search类组件的一个新的实例对象值是当前元素input,这样我们就可以在点击事件发生的时候通过this.target.value拿到我们的内容,然后发送请求的时候作为参数传给服务器。
2.受控组件
受控组件就是当我们用jsx去写一个标签元素的时候,我们可以在state中设置一个value值为空,然后给input添加onChange监听事件比如onChange={this.getValue},当监听到变化的时候,函数执行,更新this.setState({value:event.target.value}) 就也可以获取到value值。然后我们点击事件中直接用this.state.value可以直接使用value作为参数传给服务器了。
这是简单一个示例,可以帮助我们去理解。
那么我们Search组件就可以进行下一步了。发送请求获得返回数据。我们这里使用的axios第三方库。我们npm add axios安装库之后引入就可以axios方法了。
这里发送请求无非三个关键点,要有发送的地址,
还要有method params。不过我现在只是学习前端内容,这些并未涉及到,所以我只是知道有这个东西。这里我们希望是获取与我们输入内容相关的用户名信息,所以是get请求。
在这段代码中,我们用axios.get方法向https://api.hithub.com/search.users发送请求,参数是我们的value。
这是一个实例promise对象,我们在这后面用.then方法,里面的内容是如果请求发送成功,就输出response.data 也就是返回来的数据,报错就报错
这里我们控制台可以看到输出了内容,也就是我们响应体,也就是服务传给我们的数据内容。我们要展示的就是items这个数组,也就是我们要的用户信息。
这里我们是直接请求到github这个地址上的服务,为什么没有跨域呢,因为github配置了cors,虽然不知道是什么,但是有了cors大家都可以在自己的服务器上直接访问到github然后拿回数据,但是我们这样频繁的访问会出错,这时候我们就希望自己有一个代理服务器,上面有2个服务,也就是说,如果github因为频繁访问出错,我们就用服务2,里面存放固定的数据给我们,这样能保证我们只要通过代理服务器发送了请求,肯定是有数据回来的。
我们打开代理服务器
我们现在只学的前端,服务器相关的只是知道是什么就行,不用知道原理。
但是这个服务器打开了我们就会有跨域的问题了,我们setupProxy.js配置代理服务器,我上一章以及提到过了,还有一个问题是我的电脑5000端口用不了,我这个电脑5000端口一直被占用,所以我这边服务改为3002端口。
代理服务器搞定之后,我们直接访问代理服务器就可以返回数据了。
我们需要的数据是items,然后我们现在输出的是response.data,那么response.data.items就是我们要用到的items。
现在我们拿到了数据,我们只需要传给List组件就可以了。这些逻辑就是实现的逻辑,和TodoList是一样的。调用函数Search组件传返回的response.data.items用户信息给App组件,更新state,然后传给list遍历展示。
剩下的功能是,发送请求的时候,希望搜索显示loading以及展示区域有一个欢迎的效果。
那么我们首先loading,以及欢迎,还有展示的内容items,以及err。我们需要四个动态效果,也就对应四个数据动态变化驱动页面交互。我们现在先用props来传递,老公式,父组件App组件里面放state存四个数据。
然后通过函数传给Search组件,这里我们要注意的是,当发送请求前,我们的页面是第一次打开,所以默认欢迎,当点击事件发生的时候,这时候我们就isFirst改为false,isLoading改为true,然后当发送请求后,当有数据返回也就是请求成功了,我们改isLoading为false,然后传users我们的items用户信息。
剩下的就是App组件通过获取的对象直接合并更新state。然后传给List,List遍历items渲染出来用户信息到页面上,这样我们的搜索案例(axios)就完成了。
2.github搜索案例(Pubsub)
那么在标题一的下面我们是通过props来传递数据的,这样在实际开发中有点不太适合,我们现在有一种新的方式,引入Pubsub订阅发布库,用里面的方法来直接实现Search组件和List组件之间的数据传递。
这里是使用的方法,原理就像
用语言描述就是 A组件 想要 B组件的数据,那么A组件就要订阅一个 消息,然后定义消息名,B组件发布消息,然后把消息作为数据带过去给A。A订阅了就拿到了B数据。
语言说出来很难理解,但写出来就很简单。
首先不在需要App组件定义state当中间人传递数据,外壳组件可以真正的作为外壳组件使用了。那样就正常变成了,数据在那里,操作数据的方法就在那里。
List展示state,所以我们定义在List组件中。
Search组件来更新List组件里面的state,也就是说,
通过钩子,也就是当页面加载完毕,就启动订阅,然后接收的参数默认两个,我们只需要后者,前者是消息名我们不需要就省略,消息名一致就可以订阅到对应发布的数据,然后页面将要关闭也就是卸载的时候,关闭订阅方法。
然后就是Search组件在对应的时期通过PubSub.publish('me',{isLoading:false,users:response.data.items})把数据传给订阅的List组件。
订阅发布可以直接实现图中勾选组件的数据传输,而不用一层层传递。
3.github搜索案例(fetch)
那么我们现在实现了通过axios库(封装的xhr)发生请求,现在我们去学一种新的发生请求fetch,不需要引入。
这是截取某个文章的内容
中间的文字不需要在意,我们在意的是区别。不过我只学了前端,所以也暂且不用知道什么原理,只知道怎么用现在。
我们把前面axios对应的方法改成fetch
这个时候我们发现控制台输出的内容response并没有我们想要的data数据。
如果写成这样,那么response就会包含我们的items。原理大概是--
这里第一个.then为什么能用,因为fetch()是一个Promise实例对象,然后.then能链式使用,因为上一个.then返回的也是一个promise实例对象,这里的返回值指的是.then成功执行回调之后的返回值,而且返回值是一个response.json()也就是promise实例对象,如果.then指定的回调函数成功的返回值,是一个promise实例对象,那么这个promise实例对象就是整个.then方法的返回值,所以可以继续调用.then 方法
首先第一个.then有两个回调,成功的和失败的。如果成功或者失败的执行的回调函数的返回值是一个非promise值,那么外侧的.then返回的promise实例状态是成功的,值是返回的非promise值。如果返回的本身就是一个promise值,那么这个值就是外侧.then所返回的promise实例的值,如果返回的是一个成功的promise实例而且值是1,那么.then返回的promise实例状态成功而且值是1,如果返回的是一个pending状态 的promise实例,那么外侧的.then就是一个pending状态的实例,如果异常,返回的promise状态就是失败的,原因就是抛出的异常
上面是知识点,大概是这些。我只是了解即可现在。
现在是实操,现在我们的返回值是一个response.json(),意味着这个当前的then返回值是一个promise实例,值和返回的promise.json()的值是一样的,也就是我们可以继续.then是因为上面的.then返回值是promise实例而且值也是promise.json()
那么下一个.then执行response回调函数,用到promise实例对象值就是promise.json()
这是第二次输出response的结果,包含了我们想要的item。这里我们的error下了多次,实际上是没必要的,我们优化一下。
我们用.catch捕获错误如果有的话,然后输出错误。
也可以这样去写,更加简洁,这里的async异步函数,所以必须加await。但这样可能出错拿不到出错。所以我们要这样写,
这样就也可以捕获到错误并且输出了。
通过这个搜索案例,里面的ref,props,以及PubSub订阅,以及通过状态的变化来驱动页面进行交互功能,这些前端的思路是完全通的,axios,fetch这些请求,只能说能大概的知道这个案例种的使用方法。毕竟现在是在学前端,其他的还是可以放一放的。