30天入坑React ---------------day10 Interactivity

2023-10-17 05:10

本文主要是介绍30天入坑React ---------------day10 Interactivity,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这篇文章是30天React系列的一部分 。

在本系列中,我们将从非常基础开始,逐步了解您需要了解的所有内容,以便开始使用React。如果您曾经想学习React,那么这里就是您的最佳选择!

下载免费的PDF

30天的React Mini-Ebook

互动

在Github上编辑此页面

今天,我们将介绍如何为我们的应用程序添加交互性,使其具有吸引力和动态性。

通过这一点,我们构建了少数几个组件,而没有增加太多的用户交互。今天,我们要改变这一点。

用户互动

浏览器是一个事件驱动的应用程序。用户在浏览器中执行的所有操作都会触发事件,从单击按钮到甚至只是移动鼠标。在纯的JavaScript中,我们可以监听这些事件并附加的JavaScript函数来与它们进行交互。

例如,可以我们mousemove使用JS 将函数附加到浏览器事件:

export const go = () => {const ele = document.getElementById('mousemove');ele.innerHTML = 'Move your mouse to see the demo';ele.addEventListener('mousemove', function(evt) {const { screenX, screenY } = evt;ele.innerHTML = '<div>Mouse is at: X: ' +screenX + ', Y: ' + screenY +'</div>';})
}

这导致以下功能:

移动鼠标以查看演示

在阵营中,我们不必在原始的JavaScript中与浏览器的事件循环交互,因为阵营为我们提供了一种处理事件的方法props

例如,mousemove要从React上面的(相当不起眼的)演示中监听事件,我们将设置prop onMouseMove(注意事件名称的camelcasing)。

<div onMouseMove={(evt) => console.log(evt)}>Move the mouse over this text
</div>

反应了提供很多最props我们可以设置来监听不同的浏览器事件,例如点击,触摸,拖动,滚动,选择事件等等(参阅请事件文档以电子杂志所有这些事件的列表)。

要查看其中的一些实际操作,的英文以下props我们可以传递给我们的元素的一些小_ECSHOP演示。列表中的每个文本元素都会设置它列出的道具。尝试使用列表并查看在元素中如何调用和处理事件(所有事件都在文本上设置,而不是列表项):

将我们在onClick整个应用程序中使用支柱相当多,所以熟悉它是个好主意。在我们的活动列表标题中,我们有一个搜索图标,我们还没有连接到显示搜索框。

我们想要的交互的英文<input />在用户点击搜索图标种植时显示搜索。回想一下,的我们Header组件的英文这样实现的:

class Header extends React.Component {constructor(props) {super(props);this.state = {searchVisible: false}}// toggle visibility when run on the stateshowSearch() {this.setState({searchVisible: !this.state.searchVisible})}render() {// Classes to add to the <input /> elementlet searchInputClasses = ["searchInput"];// Update the class array if the state is visibleif (this.state.searchVisible) {searchInputClasses.push("active");}return (<div className="header"><div className="menuIcon"><div className="dashTop"></div><div className="dashBottom"></div><div className="circle"></div></div><span className="title">{this.props.title}</span><inputtype="text"className={searchInputClasses.join(' ')}placeholder="Search ..." />{/* Adding an onClick handler to call the showSearch button */}<divonClick={this.showSearch.bind(this)}className="fa fa-search searchIcon"></div></div>)}
}

用户当单击该<div className="fa fa-search searchIcon"></div>元素时,我们将要运行一个函数来更新组件的状态,以便searchInputClasses更新对象。使用onClick处理程序,这非常简单。

让我们使这个组件有状态(它需要跟踪搜索字段是否应该显示)。我们可以使用constructor()函数将我们的组件转换为有状态:

class Header extends React.Component {constructor(props) {super(props);this.state = {searchVisible: false}}// ...
}

的英文什么constructor功能?

在JavaScript的中,该constructor函数的英文在创建³³对象时运行的函数。它返回对创建实例的对象函数的引用prototype

简单来说,构造函数是在JavaScript的运行时创建新对象时运行的函数。我们将使用构造函数方法在对象上设置实例变量,因为它在创建对象时正确运行。

使用ES6类语法创建³³对象时,必须我们super()在任何其他方法之前调用该方法。调用该super()函数调用父类的constructor()函数。我们将使用相同的参数调用它,我们因为调用constructor()了类的函数。

当用户单击该按钮时,将我们要更新状态以表示该searchVisible标志已更新。由于我们希望用户能够在<input />第二次单击搜索图标种植后关闭/隐藏字段,因此将我们e月刊状态而不是将其设置为真。

让我们创建这个方法来绑定我们的单击事件:

class Header extends React.Component {// ...showSearch() {this.setState({searchVisible: !this.state.searchVisible})}// ...
}

最后,我们可以onClick在icon元素上附加一个单击处理程序(使用prop)来调用我们的新showSearch()方法。我们Header组件的整个更新源代码如下所示:

class Header extends React.Component {constructor(props) {super(props);this.state = {searchVisible: false}}// toggle visibility when run on the stateshowSearch() {this.setState({searchVisible: !this.state.searchVisible})}render() {// Classes to add to the <input /> elementlet searchInputClasses = ["searchInput"];// Update the class array if the state is visibleif (this.state.searchVisible) {searchInputClasses.push("active");}return (<div className="header"><div className="fa fa-more"></div><span className="title">{this.props.title}</span><inputtype="text"className={searchInputClasses.join(' ')}placeholder="Search ..." />{/* Adding an onClick handler to call the showSearch button */}<divonClick={this.showSearch.bind(this)}className="fa fa-search searchIcon"></div></div>)}
}

尝试单击搜索图标并观察输入字段的显示和消失(动画效果由CSS动画处理)。

输入事件

每当我们在React中构建表单时,我们将使用React提供的输入事件。最值得注意的是,我们最常使用onSubmit()onChange()道具。

让我们更新我们的搜索框演示,以便在更新时捕获搜索字段内的文本。每当一个<input />字段具有onChange()prop设置时,它将在每次字段改变时调用该函数。当我们点击它并开始输入时,将调用该函数。

使用此prop,我们可以捕获我们州的字段值。

我们不是更新我们的<Header />组件,而是创建一个包含<form />元素的新子组件。通过将表单处理职责移动到它自己的表单,我们可以简化<Header />代码,当我们的用户提交表单时,我们可以调用标题的父级(这是通常的React模式)。

让我们创建一个我们称之为的新组件SearchForm。这个新组件是一个有状态组件,因为我们需要保持搜索输入的值(跟踪它的变化):

class SearchForm extends React.Component {// ...constructor(props) {super(props);this.state = {searchText: ''}}// ...
}

现在,我们已经在<Header />组件中编写了表单的HTML ,所以让我们从Header组件中获取它并从我们的SearchForm.render()函数返回它:

class SearchForm extends React.Component {// ...render() {const { searchVisible } = this.state;let searchClasses = ['searchInput']if (searchVisible) {searchClasses.push('active')}return (<form className='header'><inputtype="search"className={searchClasses.join(' ')}onChange={this.updateSearchInput.bind(this)}placeholder="Search ..." /><divonClick={this.showSearch.bind(this)}className="fa fa-search searchIcon"></div></form>);}
}

请注意,我们在我们的<input />领域丢失了样式。由于我们searchVisible的新组件中不再具有状态,因此我们不能再使用它来设置样式<input />但是,我们可以从我们的Header组件传递一个prop,它告诉SearchForm将输入呈现为可见。

让我们定义searchVisibleprop(PropTypes当然使用)并更新render函数以使用新的prop值来显示(或隐藏)搜索<input />。我们还将字段可见性的默认值设置为false(因为我们的Header显示/隐藏它很好):

class SearchForm extends React.Component {static propTypes = {onSubmit: PropTypes.func.isRequired,searchVisible: PropTypes.bool}// ...
}

 

现在我们将样式返回到<input />元素上,让我们添加用户在搜索框中键入的功能,我们将要捕获搜索字段的值。我们可以通过将onChangeprop添加到<input />元素并向其传递函数来实现此工作流程,以便每次<input />更改元素时调用它。

class SearchForm extends React.Component {// ...updateSearchInput(e) {const val = e.target.value;this.setState({searchText: val});}// ...render() {const { searchVisible } = this.state;let searchClasses = ['searchInput']if (searchVisible) {searchClasses.push('active')}return (<form className='header'><inputtype="search"className={searchClasses.join(' ')}onChange={this.updateSearchInput.bind(this)}placeholder="Search ..." /><divonClick={this.showSearch.bind(this)}className="fa fa-search searchIcon"></div></form>);}
}

当我们输入字段时,updateSearchInput()将调用该函数。我们将通过更新状态来跟踪表单的价值。在updateSearchInput()函数中,我们可以直接调用this.setState()以更新组件的状态。

该值保存在event对象的目标上event.target.value

class SearchForm extends React.Component {// ...updateSearchInput(e) {const val = e.target.value;this.setState({searchText: val});}// ...
}

受控制与不受控制

我们正在创建所谓的不受控制的组件,因为我们没有设置<input />元素的值。我们现在无法对输入文本值进行任何验证或后处理。

如果我们想要验证字段或操纵<input />组件的值,我们必须创建所谓的受控组件,这实际上只意味着我们使用valueprop 传递一个值。受控组件版本的render()功能如下所示:

class SearchForm extends React.Component {render() {return (<inputtype="search"value={this.state.searchText}className={searchInputClasses}onChange={this.updateSearchInput.bind(this)}placeholder="Search ..." />);}
}

截至目前,我们无法实际提交表单,因此我们的用户无法真正搜索。让我们改变这一点。我们要将<input />组件包装在<form />DOM元素中,以便我们的用户可以按回车键提交表单。我们可以通过使用元素onSubmit上的prop 来捕获表单提交<form />

让我们更新render()函数以反映这一变化。

class SearchForm extends React.Component {// ...submitForm(e) {e.preventDefault();const {searchText} = this.state;this.props.onSubmit(searchText);}// ...render() {const { searchVisible } = this.props;let searchClasses = ['searchInput']if (searchVisible) {searchClasses.push('active')}return (<form onSubmit={this.submitForm.bind(this)}><inputtype="search"className={searchClasses.join(' ')}onChange={this.updateSearchInput.bind(this)}placeholder="Search ..." /></form>);}
}

我们马上打电话event.preventDefault()给这个submitForm()功能。这会阻止浏览器冒泡事件,这会导致整个页面的默认行为重新加载(浏览器提交表单时的默认功能)。

现在,当我们输入<input />字段并按Enter键时,将submitForm()使用事件对象调用该函数。

所以...很好,我们可以提交表格和内容,但我们什么时候才能进行搜索?出于演示的目的,现在,我们会通过搜索文本了亲子部分构成的链,因此Header可以决定什么搜索。

SearchForm组件当然不知道它在搜索什么,所以我们必须将责任传递给链。我们将使用这个回调策略。

为了将搜索功能传递给链,我们SearchForm需要接受一个支柱函数来在提交表单时调用。让我们定义一个我们称之为onSubmit可以传递给我们SearchForm组件的道具。作为优秀的开发人员,还将我们为此功能添加默认prop值和a 。由于我们要确保定义,我们将把道具设置为必需的道具:propTypeonSubmitonSubmit()onSubmit

class SearchForm extends React.Component {static propTypes = {onSubmit: PropTypes.func.isRequired,searchVisible: PropTypes.bool}// ...static defaultProps = {onSubmit: () => {},searchVisible: false}// ...
}

提交表单时,我们可以直接从中调用此函数props。由于我们在状态中跟踪搜索文本,可以我们使用searchText状态中的值调用函数,因此onSubmit()函数只获取值而不需要处理事件。

class SearchForm extends React.Component {// ...submitForm(event) {// prevent the form from reloading the entire pageevent.preventDefault();// call the callback with the search valuethis.props.onSubmit(this.state.searchText);}
}

现在,当用户按下回车键时,可以我们通过我们的组件调用此onSubmit()函数。propsHeader

可以我们SearchForm在组件中使用这个组件,Header并将它们传递给我们定义的两个道具(searchVisibleonSubmit):

import React from 'react';
import SearchForm from './SearchFormWithSubmit'class Header extends React.Component {constructor(props) {super(props);this.state = {searchVisible: false}}// toggle visibility when run on the stateshowSearch() {this.setState({searchVisible: !this.state.searchVisible})}render() {// Classes to add to the <input /> elementlet searchInputClasses = ["searchInput"];// Update the class array if the state is visibleif (this.state.searchVisible) {searchInputClasses.push("active");}return (<div className="header"><div className="menuIcon"><div className="dashTop"></div><div className="dashBottom"></div><div className="circle"></div></div><span className="title">{this.props.title}</span><SearchFormsearchVisible={this.state.searchVisible}onSubmit={this.props.onSubmit} />{/* Adding an onClick handler to call the showSearch button */}<divonClick={this.showSearch.bind(this)}className="fa fa-search searchIcon"></div></div>)}
}export default Header

现在我们有一个搜索表单组件,可以我们在我们的应用程序中使用状语从句:重用当然,我们实际上还没有搜索任何东西。让我们解决这个问题并实施搜索。

要在我们的组件中实现搜索,需要我们搜索将职责从我们的Header组件再次传递给我们将调用的容器组件Panel

首先,我们让实现从子Panel容器中的容器到Header组件的回调到父组件的相同模式。

Header组件上,我们让更新propTypes一个我们将定义为支柱的道具onSearch

class Header extends React.Component {// ...
}
Header.propTypes = {onSearch: PropTypes.func
}

Header组件的'submitForm()'函数内部,调用此onSearch()丙我们将传递给它:

class Header extends React.Component {// ...submitForm(val) {this.props.onSearch(val);}// ...
}
Header.propTypes = {onSearch: PropTypes.func
}

请注意,我们的虚拟树看起来像这样:

<Panel><Header><SearchForm></SearchForm></Header>
</Panel

<SearchForm />更新时,它会传递它对搜索输入对其父级的更改的感知<Header />,它将当向上网站传递给<Panel />组件时,此方法在作出反应程序应用中非常常见,并为我们的组件提供了一组良好的功能隔离。

回到Panel我们在第7构建天的组件中,将我们函数传递给Header作为onSearch()支柱的函数Header。我们在这里说的是,当提交搜索表单时,我们希望搜索表单回调到标题组件,调用然后Panel组件来处理搜索。

由于Header组件不控制内容列表,Panel组件确实如此,我们必须将责任再提高一级,正如我们在此定义的那样。

无论如何,的我们Panel组件基本上的英文Content我们之前处理过的组件的副本:

class Panel extends React.Component {constructor(props) {super(props);this.state = {loading: false, // <~ set loading to falseactivities: data,filtered: data,}}componentDidMount() {this.updateData();}componentWillReceiveProps(nextProps) {// Check to see if the requestRefresh prop has changedif (nextProps.requestRefresh !== this.props.requestRefresh) {this.setState({loading: true}, this.updateData);}}handleSearch = txt => {if (txt === '') {this.setState({filtered: this.state.activities})} else {const { activities } = this.stateconst filtered = activities.filter(a => a.actor && a.actor.login.match(txt))this.setState({filtered})}}// Call out to github and refresh directoryupdateData() {this.setState({loading: false,activities: data}, this.props.onComponentRefresh);}render() {const {loading, filtered} = this.state;return (<div><HeaderonSubmit={this.handleSearch}title="Github activity" /><div className="content"><div className="line"></div>{/* Show loading message if loading */}{loading && <div>Loading</div>}{/* Timeline item */}{filtered.map((activity) => (<ActivityItemkey={activity.id}activity={activity} />))}</div></div>)}
}

我们让我们更新的状态以所有游戏一个searchFilter字符串,它只是搜索值:

class Panel extends React.Component {constructor(props) {super(props);this.state = {loading: false,searchFilter: '',activities: []}}
}

为了实际处理搜索,我们需要将一个onSearch()函数传递给我们的Header组件。让我们onSearch()Panel组件中定义一个函数,并将其传递给函数中的Header道具render()

class Panel extends React.Component {// ...// after the content has refreshed, we want to// reset the loading variableonComponentRefresh() {this.setState({loading: false});}handleSearch(val) {// handle search here}render() {const {loading} = this.state;return (<div><HeaderonSearch={this.handleSearch.bind(this)}title="Github activity" /><ContentrequestRefresh={loading}onComponentRefresh={this.onComponentRefresh.bind(this)}fetchData={this.updateData.bind(this)} /></div>)}
}

在我们这里所做的就是添加一个handleSearch()函数并将其传递给标题。现在,当用户在搜索框中键入时,将handleSearch()调用我们Panel组件上的函数。

实际要实现搜索,需要我们跟踪此字符串并更新我们的updateData()功能以考虑搜索过滤。首先,我们让设置searchFilter状态。我们还可以Content通过设置loading为真来强制重新加载数据,因此我们可以一步完成:

class Panel extends React.Component {// ...handleSearch(val) {this.setState({searchFilter: val,loading: true});}// ...
}

最后,我们让我们更新的updateData()功能以考虑搜索

class SearchableContent extends React.Component {// ...this.setState({loading: true}, this.updateData);// ...
}

虽然这可能看起来很复杂,它但实际上几乎与我们现有的updateData()函数完全相同,除了我们更新fetch()查询查询结果以调用filter()JSON集合上的方法。

所有collection.filter()函数都运行为每个元素传入的函数,并过滤报道查看虚假值的值,保留返回真值的值。我们的搜索功能只是在Github的活动actor.login(Github的用户)上查找匹配,以查看它是否与该searchFilter值匹配。

随着updateData()功能的更新,我们的搜索已经完成。

尝试搜索auser

现在我们有一个3层应用程序组件,用于处理嵌套子组件的搜索。我们用这篇文章从初学者跳到中级。拍拍自己的背部。这是一些沉重的材料。请确保您理解这一点,因为我们会经常使用我们今天介绍的这些概念。

在下一节中,我们将跳出来看看构建组件。

 

学习REACT正确的方法

React和朋友的最新,深入,完整的指南。

下载第一章

❮上一个

下一章:

纯组件

这篇关于30天入坑React ---------------day10 Interactivity的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/223144

相关文章

30常用 Maven 命令

Maven 是一个强大的项目管理和构建工具,它广泛用于 Java 项目的依赖管理、构建流程和插件集成。Maven 的命令行工具提供了大量的命令来帮助开发人员管理项目的生命周期、依赖和插件。以下是 常用 Maven 命令的使用场景及其详细解释。 1. mvn clean 使用场景:清理项目的生成目录,通常用于删除项目中自动生成的文件(如 target/ 目录)。共性规律:清理操作

2024网安周今日开幕,亚信安全亮相30城

2024年国家网络安全宣传周今天在广州拉开帷幕。今年网安周继续以“网络安全为人民,网络安全靠人民”为主题。2024年国家网络安全宣传周涵盖了1场开幕式、1场高峰论坛、5个重要活动、15场分论坛/座谈会/闭门会、6个主题日活动和网络安全“六进”活动。亚信安全出席2024年国家网络安全宣传周开幕式和主论坛,并将通过线下宣讲、创意科普、成果展示等多种形式,让广大民众看得懂、记得住安全知识,同时还

js react 笔记 2

起因, 目的: 记录一些 js, react, css 1. 生成一个随机的 uuid // 需要先安装 crypto 模块const { randomUUID } = require('crypto');const uuid = randomUUID();console.log(uuid); // 输出类似 '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'

React 笔记 父子组件传值 | 父组件调用子组件数据 | defaultProps | propsType合法性验证

1.通过props实现父组件像子组件传值 、方法、甚至整个父组件 传递整个父组件则   [变量名]={this} import Header from "./Header"render(){return(<Header msg={"我是props传递的数据"}/>)} import React,{Component} from "react";class Header extends

react笔记 8-21 约束性 表单

1、约束性组件和非约束性组件 非约束性组件<input type="text" name="" defaultValue={this.state.msg}></input>这里他的value是用户输入的值 并没有执行操作 只是获取到了msg的值 用户输入不会改变数据非约束性组件需要使用defaultValue获取数据 否则会报错约束性组件<input type="text

react笔记 8-19 事件对象、获取dom元素、双向绑定

1、事件对象event 通过事件的event对象获取它的dom元素 run=(event)=>{event.target.style="background:yellowgreen" //event的父级为他本身event.target.getAttribute("aid") //这样便获取到了它的自定义属性aid}render() {return (<div><h2>{

react笔记 8-18 事件 方法 定义方法 获取/改变数据 传值

1、定义方法并绑定 class News extends React.Component {constructor(props) {super(props)this.state = {msg:'home组件'}}run(){alert("我是一个run") //方法写在类中}render() {return (<div><h2>{this.state.msg}</h2><button onCli

react笔记 8-17 属性绑定 class绑定 引入图片 循环遍历

1、绑定属性 constructor(){super()this.state={name:"张三",title:'我是一个title'}}render() {return (<div><div>aaaaaaa{this.state.name}<div title={this.state.title}>我是一个title</div></div></div>)} 绑定属性直接使用花括号{}   注

react笔记 8-16 JSX语法 定义数据 数据绑定

1、jsx语法 和vue一样  只能有一个根标签 一行代码写法 return <div>hello world</div> 多行代码返回必须加括号 return (<div><div>hello world</div><div>aaaaaaa</div></div>) 2、定义数据 数据绑定 constructor(){super()this.state={na

2021-8-14 react笔记-2 创建组件 基本用法

1、目录解析 public中的index.html为入口文件 src目录中文件很乱,先整理文件夹。 新建components 放组件 新建assets放资源   ->/images      ->/css 把乱的文件放进去  修改App.js 根组件和index.js入口文件中的引入路径 2、新建组件 在components文件夹中新建[Name].js文件 //组件名首字母大写