React基础

您所在的位置:网站首页 js监听onclick事件 React基础

React基础

2023-03-24 18:52| 来源: 网络整理| 查看: 265

前言与原生浏览器事件相比相同不同this实战加入当前地点

前言

浏览器原生的 addEventListener 允许我们进行事件监听,React 同样提供了一套事件监听的机制:使用 on* 属性。

例如监听按钮的 click 事件:

function handleClick() { console.log('Click');}btn

注意:若不经处理,on* 事件监听只能用在 HTML 的标签上,不能用在组件标签上。

与原生浏览器事件相比

相同

React 事件与原生浏览器事件拥有同样的接口,同样支持事件的冒泡机制:使用 stopPropagation() 和 preventDefault() 来中断。

举个栗子:

function handleClick(e) { console.log(e.target.innerHTML);}btn

这样每次点击按钮,就会打印按钮的 innerHTML。

不同

与原生浏览器事件不同的是,在 JSX 内使用驼峰式写法(例如 onClick),HTML 事件使用全小写(例如 onclick)。并且 HTML 通过写 JavaScript 代码字符串直接写入了 HTML 属性内,React 则更像是事件委派的机制。

this

this 一直是一个令 JavaScript 初学者头疼的东西,如果你对 this 一点不了解的话推荐你看一下 MDN 对 this 的讲解。简单讲,this 就是指向方法的调用者。

使用 class component 并且绑定事件时,不可避免的要手动实现 this 的绑定。

列举几种绑定 this 的方式:

bind。bind 方法返回一个函数,函数的 this 指向 bind 的第一个参数。缺点是每次调用 onClick 事件时都会生成一个新的函数。 class Demo extends React.Component { handleClick() { console.log('hello'); } render() { return ( btn ) }} 构造器内声明。在构造器内绑定 this,这样的好处是仅绑定一次,不存在无用的重复绑定,推荐使用这种方式。 class Demo extends React.Component { constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); } handleClick() { console.log('hello'); } render() { return ( btn ) }} 箭头函数。箭头函数没有 this,所以需要继承定义箭头函数所在的作用域的 this。 class Demo extends React.Component { // 我更倾向于构造器内声明,这种写法严格讲应该是类的实例属性而不是方法 handleClick = () => { console.log('hello'); } render() { return ( btn ) }}// 或者class Demo extends React.Component { handleClick() { console.log('hello'); } render() { return ( // 不推荐 每次调用 onClick 事件时都会生成一个新的函数 this.handleClick()}>btn ) }}

实战

我们利用事件实现可交互的天气查询。

加入当前地点

接口内已经有了当前查询的地点,我们取出渲染即可:

class App extends React.Component { state = { city: null, realTimeData: [], weatherDetailsData: [], indexesData: [], } componentDidMount() { fetch('/app/weather/listWeather?cityIds=101240101') .then(res => res.json()) .then((res) => { if (res.code === '200' && res.value.length) { const { city, realtime, weatherDetailsInfo, indexes } = res.value[0]; const { weather3HoursDetailsInfos } = weatherDetailsInfo; this.setState({ city, realTimeData: realtime, weatherDetailsData: weather3HoursDetailsInfos, indexesData: indexes, }); } }); } render() { const { city, realTimeData, weatherDetailsData, indexesData } = this.state; return ( {city} ); }}

下一步,我们希望点击当前的地点,弹出输入框,并根据输入框输入的城市更新天气信息。

首先写一个 City 组件,将展示的内容一并放入组件内:

class City extends React.Component { constructor(props) { super(props); this.state = { visible: false, } this.handleVisible = this.handleVisible.bind(this); } handleVisible() { this.setState({ visible: true, }); } render() { const city = this.props.data; const { visible } = this.state; return ( {city} { visible && ( 查询 ) } ) }}

这样我们就实现了一个点击就出现的弹框。

事件监听 - 图1

然后我们点击查询按钮时,需要先获取输入框输入的内容,然后根据内容更新天气信息。

我们可以通过 state 来控制输入框输入,每输入一个字符 state 就做出相应变化(通过监听 onChange 事件)。即 state === 输入内容:

class City extends React.Component { constructor(props) { super(props); this.state = { visible: false, input: '', } this.handleVisible = this.handleVisible.bind(this); this.handleChange = this.handleChange.bind(this); } handleVisible() { this.setState({ visible: true, }); } handleChange(e) { this.setState({ input: e.target.value, }); } render() { const city = this.props.data; const { visible, input } = this.state; return ( {city} { visible && ( 查询 ) } ) }}

就差最后一步了,点击查询按钮获取到输入框内输入的城市的天气。

由于我们接口传入的是城市的 id,我找到了一份市区 id 对应的json数据用于查询输入城市对应的 id:

import { cities } from './static/city.json';class City extends React.Component { constructor(props) { super(props); this.state = { visible: false, input: '', } this.handleVisible = this.handleVisible.bind(this); this.handleChange = this.handleChange.bind(this); this.handleSearch = this.handleSearch.bind(this); } handleVisible() { this.setState({ visible: true, }); } handleChange(e) { this.setState({ input: e.target.value, }); } handleSearch() { const { input } = this.state; if (input) { const result = cities.find(item => item.city === input); if (result) { // 更新天气并关闭当前弹框 // todo 更新天气 this.setState({ visible: false, input: '', // 关闭弹框后清空输入 }); } else { alert('没有查询到相应城市') } } else { alert('没有输入要查询的城市') } } render() { const city = this.props.data; const { visible, input } = this.state; return ( {city} { visible && ( 查询 ) } ) }}

到这里就差最后一步,点击查询后将城市 id 传给父组件,最简单的,我们可以通过类似回调的方式传递:

// 首先我们给组件 City 增加一个 props onCityChangehandleCityChange = id => { // 在这里更新天气数据}// 在组件 City 内部,我们只需要调用 props.onCityChange 并传入城市 id 等数据即可this.props.onCityChange(result.cityid)

我们更新一下父组件请求接口数据的地方:

// 将请求数据抽离,可复用 getData(id) { fetch(`/app/weather/listWeather?cityIds=${id}`) .then(res => res.json()) .then((res) => { if (res.code === '200' && res.value.length) { const { city, realtime, weatherDetailsInfo, indexes } = res.value[0]; const { weather3HoursDetailsInfos } = weatherDetailsInfo; this.setState({ city, realTimeData: realtime, weatherDetailsData: weather3HoursDetailsInfos, indexesData: indexes, }); } }); } componentDidMount() { // 默认请求北京的天气,当然可以拓展 例如利用定位获取当前位置,或者要求用户输入位置 this.getData('101010100'); } handleCityChange = cityid => { this.getData(cityid); }

好啦到这里我们的实战就完成啦。实战源码

我们的实战仍然有优化的空间,例如将各个组件分别写入不同的文件内,最后在 App.js 内统一引入各个组件。

希望这些内容能对大家有所帮助。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3