React学习之受控组件与数据共享实例分析

本文实例讲述了React学习之受控组件与数据共享。分享给大家供大家参考,具体如下:

在HTML当中,像<input>,<textarea>, 和 <select>这类表单元素会自己储存值,并且根据用户输入进行更新。但在React中,可变的值通常保存在组件的state中,并且只能用 setState() 方法进行更新。为了解决二者的矛盾,可以让HTML元素不再自己储存数据,而使用来自于react的state。也就是说HTML元素把数据保存在react组件的state中,并根据state值来渲染更新HTML的内容。这种值由React控制的表单元素称为受控组件。

1、input

例如将input输入的名字保存在state.name中,并且设置input显示的value值为state.name。当input中输入变化时,onChange触发updateName函数更新name值,从而使input中显示的value发生变化。当点击提交按钮时onClick触发submit()方法来阻止默认的提交,并打印提示信息:

class ControlledForm extends React.Component{
 constructor(props){
  super(props);
  this.state={
   name:''
  };
  this.updateName=this.updateName.bind(this);
  this.submit=this.submit.bind(this);
 }
 updateName(e){        //在调用函数时会默认传入时间参数e
  this.setState({
   name:e.target.value    //更新name的值为input中输入的值
  })
 }
 submit(e){          //自己定义点击submit后的操作
  console.log("姓名"+this.state.name+"提交成功");
  e.preventDefault();     //阻止表单默认提交行为
 }
 render(){
  return (
   <form onSubmit={this.submitForm}>
     <label>
       姓名:
       <input type="text" value={this.state.name} onChange={this.updateName} />
     </label>
     <input type="submit" value="提交" onClick={this.submit} />
   </form>
  )
 }
}

使用受控组件使得页面的数据都处于react的控制之下,而且可以对其数据进行处理之后再渲染到页面上。

2、textarea

在React中使用<textarea>:为了对textarea的输入内容进行控制,react中的textarea像input一样由value来控制其显示的值,并且通过e.target.value将textarea中的值存入state中。textarea的使用也由闭合式标签<textarea></textarea>变为开放式标签:

<textarea value={this.state.text} onChange={this.updateText} />

3、select

同理,在React中的<select>也通过value来控制哪个option的选中,并通过e.target.value将选中的option的值传给state。例如和this.state.sex值相同的option会被显示选中

<select value={this.state.sex} onChange={this.updateSex}>
  <option value="male">男</option>
  <option value="female">女</option>
</select>

4、利用name处理多个受控组件

如上,我们需要为每个受控组件都设置更新方法onChange,而且每个组件的更新方法都很类似,这样看起来很麻烦,我们可以根据name属性区分不同的组件所对应的state值,利用一个函数来实现多个组件state值的更新:

<select value={this.state.sex} name="sex" onChange={this.updateForm}>
updateForm(e){
 let name=e.target.name;     //获取组件的name
 let value=e.target.value;    //获取组件的值value
 this.setState({
  [name]:value         //为不同name的组件设置value
 })
}

在setState方法中,通过ES6的语法计算属性[],在中括号中指定要更新的属性名的表达式来更新不同的state。例如当select调用updateForm()时,name="sex",value="male",则通过setState将state.sex值设为male。

5、组件间数据共享

当两个组件要同时使用一个变量时,由于state只能被它所定义的组件修改、访问,因此不能把state赋给某个组件,而应该将state提升至两个组件最近的公共父组件,父组件再通过props将值传递给子组件,这样两个子组件就都可以访问了。那么子组件怎么去修改父组件的state呢?子组件通过props属性来调用父组件的方法从而修改父组件的state,这样两个组件就通过父组件实现了对state的共享。例如父组件Parent的一个子组件ChildInput负责接收用户的输入,保存在state.text中,在另一个子组件ChildShow中显示用户的输入:

class Parent extends React.Component{
 constructor(props){
  super(props);
  this.state={
   text:''
  };
  this.updateText=this.updateText.bind(this);
 }
 updateText(value){
  this.setState({
   text:value
  })
 }
 render(){
  return (
   <fieldset>
     <legend>提升state</legend>    //父组件updateInput属性指向updateText方法
     <ChildInput text={this.state.text} updateInput={this.updateText}/>
     <ChildShow text={this.state.text} />
   </fieldset>
  )
 }
}
class ChildInput extends React.Component{
 constructor(props){
  super(props);
  this.handleChange=this.handleChange.bind(this);
 }
 handleChange(e){    //在子组件的方法中调用父组件的updateInput更新text的值
  this.props.updateInput(e.target.value);
 }
 render(){
  return (
   <div>
     <label>
       请输入:
       <input type="text" value={this.props.text} onChange={this.handleChange}/>
     </label>
   </div>
  )
 }
}
class ChildShow extends React.Component{
 constructor(props){
  super(props);    //通过调用父组件构造方法将父组件的props传递给子组件
 }
 render(){
  return (
   <div>
     <p>输入为:{this.props.text}</p>
   </div>
  )
 }
}
ReactDOM.render(
 <Parent/>,
 document.getElementById('app')
)

运行结果如图:

上例在react中的数据流动如下:

1、当在input中中输入内容时,input内容改变onChange触发ChildInput组件的handleChange方法,该方法通过this.props调用父组件updateInput方法并传递输入的内容e.target.value。

2、父组件Parent在引用子组件ChildInput时为其定义updateInput属性为this.updateText方法,因此触发updateText方法,在该方法中接收子组件传递的参数value,并通过setState方法修改state.text的值。

3、当state.text值发生改变时,父组件Parent通过属性props将值传递给子组件ChildInput与ChildShow,引起子组件属性改变,从而子组件重新渲染页面内容。

希望本文所述对大家React程序设计有所帮助。

(0)

相关推荐

  • 浅谈react受控组件与非受控组件(小结)

    我们都知道,有许多的web组件可以被用户的交互发生改变,比如:<input>,<select>,或者是我现在正在使用的富文本编辑器.这些组件在日常的开发中很不显眼,我们可以很轻易的通过输入一些内容或者设置元素的value属性来改变组件的值.但是,因为React是单向数据流绑定的,这些组件可能会变得失控: 1.一个维护它自己state里的value值的<Input>组件无法从外部被修改: 2.一个通过props来设置value值的<Input>组件只能通过外部

  • 深入理解React中es6创建组件this的方法

    首发于:https://mingjiezhang.github.io/. 在JavaScript中,this对象是运行时基于函数的执行环境(也就是上下文)绑定的. 从react中的demo说起 Facebook最近一次更新react时,将es6中的class加入了组件的创建方式当中.Facebook也推荐组件创建使用通过定义一个继承自 React.Component 的class来定义一个组件类.官方的demo: class LikeButton extends React.Component

  • 用react-redux实现react组件之间数据共享的方法

    上篇文章写到了redux实现组件数据共享的方法,但是在react中,redux作者提供了一个更优雅简便的模块实现react组件之间数据共享.那就是利用react-redux 利用react-redux实现react组件数据之间数据共享 1.安装react-redux $ npm i --save react-redux 2.从react-redux导入Prodiver组件将store赋予Provider的store属性, 将根组件用Provider包裹起来. import {Provider,c

  • 浅谈React深度编程之受控组件与非受控组件

    受控组件与非受控组件在官网与国内网上的资料都不多,有些人觉得它可有可不有,也不在意.这恰恰显示React的威力,满足不同规模大小的工程需求.譬如你只是做ListView这样简单的数据显示,将数据拍出来,那么for循坏与 {} 就足够了,但后台系统存在大量报表,不同的表单联动,缺了受控组件真的不行. 受控组件与非受控组件是React处理表单的入口.从React的思路来讲,作者肯定让数据控制一切,或者简单的理解为,页面的生成与更新得忠实地执行JSX的指令. 但是表单元素有其特殊之处,用户可以通过键盘

  • React组件的三种写法总结

    React 专注于 view 层,组件化则是 React 的基础,也是其核心理念之一,一个完整的应用将由一个个独立的组件拼装而成. 截至目前 React 已经更新到 v15.4.2,由于 ES6 的普及和不同业务场景的影响,我们会发现目前主要有三种创建 React 组件的写法:1. ES5写法React.createClass,2. ES6写法React.Component,3. 无状态的函数式写法(纯组件-SFC). 你们最钟爱哪种写法呢?萝卜青菜各有所爱~ 每个团队都有自己的代码规范和开发模

  • react-native动态切换tab组件的方法

    在APP中免不了要使用tab组件,有的是tab切换,也有的是tab分类切换. 这些组件分成下面两种. 第一种非常简单,同时大多数第三方组件都能达到效果.这里重点讲述第二种,我们要让第二种组件不仅能左右滑动,同时还能够在点击的时候自动滑动,将点击的位置滑动到正中间. 准备 我们先来分析一波.一个滑动组件在APP上是一种什么状态. 这里可以看出,tab组件需要考虑到长度超过APP的屏幕,并且在超过之后能够滑动. 同时计算出当前位置需要滑动多少距离才能够将位置居中. 需要滑动的位置=点击位置的左边距-

  • 详解React中传入组件的props改变时更新组件的几种实现方法

    我们使用react的时候常常需要在一个组件传入的props更新时重新渲染该组件,常用的方法是在componentWillReceiveProps中将新的props更新到组件的state中(这种state被成为派生状态(Derived State)),从而实现重新渲染.React 16.3中还引入了一个新的钩子函数getDerivedStateFromProps来专门实现这一需求.但无论是用componentWillReceiveProps还是getDerivedStateFromProps都不是

  • React 子组件向父组件传值的方法

    本文介绍了React 子组件向父组件传值的方法,分享给大家 子组件需要控制自己的 state, 然后告诉父组件自己的state,通过props调用父组件中用来控制state的函数,在父组件中展示子组件的state变化. /***实现在输入框输入邮箱时,在div中即时显示输入内容***/ <body> <div id="test"></div> </body> //子组件 var Child = React.createClass({ re

  • react 父组件与子组件之间的值传递的方法

    概念上,组件是封闭的环境.React中是单向数据流的设计,也就是是说只有父组件传递资料给子组件这回事.以正确的技术说明,拥有者组件可以设置被拥有者组件中的数据. 那么子组件要如何与父组件沟通这件事,简单的来说,是一种迂回的作法,在父组件中设置了一个方法(函数),然后传递给子组件的props,子组件在事件触发时,直接呼叫这个props所设置的方法(函数).但这中间,有谁(对象)呼叫了函数的设置,也就是this的作用. 父组件到子组件用props设置,子组件到父组件用上面说的方式,这是基本的套路,但

  • 使用React实现轮播效果组件示例代码

    前言 我发现React和AngularJS思想完全不同,AngularJS是基于双向绑定,在Modal层中定制数据,然后双向改变.但是React是通过prop和state来改变view层的状态.下面是我写的一个轮播图组件,可以直接看一下.代码很简单.原理就是通过React在componentDidMount后改变setState,来动态改变css样式. 说明以下:看gif很卡,但是实际效果还是很好的. 以下是示例代码 LunBo.js require('styles/App.css'); req

  • React 使用Hooks简化受控组件的状态绑定

    开始之前 阅读本文需要对以下几项有一定了解 ECMAScript 6 文章中大量用到了 ES6 语法,比如解构赋值和函数参数默认值.剩余参数.展开语法.箭头函数等. Hooks React 在 16.8 版本中推出了 Hooks,它允许你在"函数组件"中使用"类组件"的一些特性. React 本身提供了一些 Hooks,比如 useState.useReducer 等.通过在一个以"use"作为命名起始的函数中调用这些 Hooks,就得到了一个

  • React如何利用相对于根目录进行引用组件详解

    前言 本文主要给大家介绍了关于React利用相对于根目录进行引用组件的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 在对自己开发的组件中经常会做诸如以下的引用: import genFetchEntryListArgs from '../../../utils/table/genFetchEntryListArgs'; import { parseQuery, stringifyQuery } from '../../../utils/query'; import

随机推荐