React 学习笔记_4(可控组件(State)与不可控组件(Ref))

Ref

在典型的 React中,props 是 父层与子层唯一的互动方式。藉由使用新的 prop 重新 render 来改变你的子层。

什么时候该使用 Ref

管理 focus、选择文字、影音播放。触发即时的动画与第三方 DOM 函式库整合

不要过度使用 Ref

建立 Ref

class Login extends React.Component{    //建立Ref    emailRef = React.createRef();    passwordRef = React.createRef();        //存取Ref    const formData = {        email:this.emailRef.current.value,        passwordRef:this.passwordRef.current.value    };        render()    {        return(            <input class="input" type="text" placeholder="Email" ref={this.emailRef}/>            <input class="input" type="text" placeholder="Password" ref={this.passwordRef} />        )    }};export default Login;

state

重点

通常会在component的 constructor 设定state初始值。
1.使用constructor设定初始值
class Like extends React.Component{    constructor()    {        super();        this.state = {            isLike:false; //预设为false        }    }}

2.使用state设定初始值

class Like extends React.Component{    state = {        isLike:false //预设为false    }}
要改变state,必须使用setState()。
class Like extends React.Component{    //设定预设值    state = {        isLike:false, //预设为false        const:0 //预设const = 0    }        //建立Event Function    handleClick() => {        //取得当前状况并对状况进行处理        this.setState({            isLike: !this.state.isLike, //取得当前状态并进行反转            const:this.state.const + 1 //取得当前状况并+1        });                //若要取得上一个对象的状态需要使用箭头函数        this.setState(prevState => {            return{                count : prevState.const + 2            };        });       };        render()    {        return(            <button className = "button is-fullwidth is-primary" onClick = {this.handleClick}>                {this.state.isLike? "No":"Yes"}            </button>        )    }}

可控组件(Controlled component)与不可控组件(Uncontrolled component)

不可控组件(Uncontrolled component)

如果要写一个 uncontrolled component,你可以使用 ref 来从 DOM 取得表单的资料

由Ref取得input的Data,并当form的Submit被触发后进入function "handleSubmit",将Ref中的data取出
(this.input.current.value)

class NameForm extends React.Component{    //建立constructor    constructor()    {        super();        //使用bind複製function handleSubmit并将this(自身class)指定给他,进行this绑定        this.handleSubmit = this.handleSubmit.bind(this);        //使用Ref取得input资料        input = React.createRef();    }        handleSubmit = (event) =>{        alert('A name was submitted: ' + this.input.current.value);        //取消默认行为        event.preventDefault();    }        render()    {        return(            <form onSubmit={this.handleSubmit}>                <label>Name:<input type="text" ref={this.input} /> </label>                <input type="submit" value="Submit" />            </form>        );    }};
预设值:在React的render生命週期里,表单的"value attribute"会覆盖掉DOM的值,在使用uncontrolled component会希望表单设定初始值但又在更新后保值不可控制,这种情况可以使用"defaultValue "
render(){    return(        <form onSubmit={this.handleSubmit}>            //使用defaultValue设定表单的value            <label> Name:<input defaultValue="Fandix"  type="text"  ref={this.input} /></label>        </form>    )}

可控组件(controlled component)

在 HTML 中,表单的 element 像是 "input"、"textarea" 和 "select" 通常会维持它们自身的 state,并根据使用者的输入来更新 state。在 React 中,可变的 state 通常是被定义在 component 中的 state property,并只能以 setState() 来更改期内容。我们可以透过将 React 的 state 变成「单一数据源」让render表单的React component可以掌握使用者的输入

当input的值发生改变(触发onChange进入function "handleChange")function会将使用者输入的值利用setState将input的state进行更改,而当onSubmit被触发后进入function handleSubmit再将被改变的state中的Data取出。

class NameForm extends React.Component {    //建立constructor    constructor()    {        super();        //绑定function的this        this.handleChange = this.handleChange.bind(this);        this.handleSubmit = this.handleSubmit.bind(this);    }        //设定state内容    state = {        value: ""    }        handleChange(event)     {        //变更State的值需要使用setState        this.setState({value: event.target.value});    }    handleSubmit(event)     {        alert('A name was submitted: ' + this.state.value);         //取消默认行为        event.preventDefault();    }      render()     {        return (          <form onSubmit={this.handleSubmit}>              <label>Name:                  <input type="text" value={this.state.value} onChange={this.handleChange} />              </label>              <input type="submit" value="Submit" />          </form>    );  }}

由于 value attribute 是被设定在input上,显示的 value 会永远是 this.state.value,这使得 React 的 state 成为了资料来源。由于 handleChange 在每一次键盘被敲击时都会被执行,并更新 React 的 state,因此被显示的 value 将会在使用者打字的同时被更新。

处理多个输入

当你需要处理多个 controlled input element,可以在每个 element 中加入一个 name,让 handler function 选择基于 event.target.name 的值进行判断

class Reservation extends React.Component {    construtor()    {        super();        //绑定function的this        this.handleInputChange = this.handleInputChange.bind(this);    }        //设定state内容    state = {        isGoing:true,        numberOfGuests:2    }        handleInputChange = (event) =>{        const target = event.target;        const value = target.name === 'isGoing' ? target.checked : target.value;        const name = target.name;                this.setState({            [name]:value        });    }        render()    {        return(            <form>                <label>                  Is going:                  <input                    name="isGoing"                    type="checkbox"                    checked={this.state.isGoing}                    onChange={this.handleInputChange} />                </label>            <br />                <label>                    Number of guests:                    <input                        name="numberOfGuests"                        type="number"                        value={this.state.numberOfGuests}                        onChange={this.handleInputChange} />                </label>          </form>       );    }};

当两个input发生改变就会进入function "handleInputChange" 判断event.name是不是input1,若是就更新name = isGoing中的State(isGoing),若不是则更新name = "numberOfGuests"中的State(numberOfGuests)。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章