setState,受控组件和非受控组件以及组件的传值
1.state:
constructor(props){
super(props)
this.state:{//永远不要直接修改state的值,否则视图不会同步
key:value
}
}
2.setState:用于更改state
在componentDidMount(){
this.setState({
key:this.state.key+1
})
}
3.类组件中的事件处理函数一定要绑定this
例如:onClick = this.add.bind(this)
第一种:尽量在构造函数中去绑定this(尽量在构造函数中去绑定,因为只执行一次)
第二种:箭头函数(因为箭头函数没有this,所以会向上找,点击触发render)
change=()=>{
}
setState的重复问题:
1.setState执行多次时,(同样代码,三个setState代码)但还是执行了一次
当你点击时,react会将代码进行合并覆盖,然后触发render,,并且看到的结果是最后一段代码
2.setState(异步操作),控制台和页面不同步,要想拿到新的值,在回调里面写
例如:this.setState({
key:新的值
},()=>{console.log(this.state.n)})//拿到新的值
2.如果多次都执行的方法,在回调里面写(则执行多次代码)
this.setState((prestate,props)=>{
return{
n:prestate.n+1
}
})
受控组件
1、什么是受控组件?
其值由React控制的输入表单元素称为“受控组件”。
2、受控组件有两个特点:1. 设置value值,value由state控制,2. value值一般在onChange事件中通过setState进行修改
3、什么时候使用受控组件?
需要对组件的value值进行修改时,使用受控组件。比如:页面中有一个按钮,每点击一次按钮受控组件的值加1.
非受控组件
1、什么是非受控组件?
表单数据由 DOM 处理的组件非受控组件。
2、非受控组件有两个特点:1. 不设置value值,2. 通过ref获取dom节点然后再取value值
<input type="text" placeholder="请输入姓名" name='username' ref={(input) => this.usernameElem = input}/>
取值方法:this.usernameElem.value
*实例代码:
componentDidMount() {
console.log(this.textInput)
}
render() {
return (
<div>
<input type="text" onKeyUp={this.keyup} ref={input => this.textInput = input} />
</div>
)
}
事件处理数的最后一个参数就是事件对象
例如:
<input type="text" onKeyUp={this.keyup} ref={input => this.textInput = input} />
keyup = (e) => {
if (e.keyCode === 13) {
console.log(e)
}
}
事件处理函数可以进行传参
this.方法名.bind(this,参数)
方法名(p){
this.setState({
key:value
})
}
组件传值
一、父子传值(props接收)
1.将父组件的数据传给子组件,因为父组件引入了子组件,在子组件的标签中中将数据传过去
2.子组件中用props接收,在constructor中console.log(this.props.data)则会拿到data数据,此时this.state=(n:this.props.state)得到数据进行渲染
父组件:App 子组件:One
1、传数值类型:
App:<one a={'222'}/>
one:this.props.a
2、传对象类型
App:var obj={a:1,b:2,c:3} <one {...obj}/>
One:this.props.obj
3、传方法
App:fun={fun} 方法
One:var fun = this.props.fun fun(213)
二、子父传值(在父组件引入的在子组件中需要将一个方法传给子组件,子组件触发这个函数完成数据更新)
1.父组件引入的子组件中传递一个方法给子组件,子组件通过this.props.传过来的方法名拿到父组件传过来的方法,在子组件的方法中将传过来的方法引用
举例说明:
父组件:
import React from 'react';
import Count from "./components/Count"
import './App.css';
export default class App extends React.Component {
constructor(props){
super(props)
this.num=[3,7,6]
var sum=this.num.reduce((a,b)=>a+b);//reduce方法进行运算
this.state={
sum
}
}
add=(p)=>{
// console.log(p)
this.setState({
sum:this.state.sum+p
})
}
render() {
return (
<div className="App">
{
this.num.map((item,index)=>{
return <Count add={this.add} n={this.num[index]} key={index}/>
})
}
<div>{this.state.sum}</div>
</div>
)
}
}
子组件:
import React, { Component } from 'react'
export default class Count extends Component {
constructor(props){
super(props)
console.log(props.n)
this.state={
n:this.props.n
}
}
inc=(p)=>{
this.setState({
n:this.state.n+p
},()=>{this.props.add(p)})
}
render() {
return (
<div>
<button id="b1" onClick={this.inc.bind(this,1)}> +</button>
{this.state.n}
<button id="b2" onClick={this.inc.bind(this,-1)}>-</button>
</div>
)
}
}
非父子组件传值(
PubSub.publish("事件名","数据")
PubSub.subscribe("事件名",(msg,data)=>{ })
1.安装pubsub-js,
2.点击发送数据( PubSub.publish('evt','hello'))
3.另外一个组件接收( PubSub.subscribe)
)
第一个组件
import React, { Component } from 'react'
import PubSub from 'pubsub-js
export default class Four extends Component {
constructor(props){
super(props)
this.state={
str:''
}
//另外一个组件接收
PubSub.subscribe('evt',(msg,data)=>{
console.log(msg,data)
this.setState({
})
})
}
render() {
return (
<div>
</div>
)
}
}
第二个组件
import React, { Component } from 'react'
import PubSub from "pubsub-js"
export default class Three extends Component {
send=()=>{
PubSub.publish('evt','hello')
}
render() {
return (
<div>
<button onClick={this.send}>send</button>
</div>
)
}
}
在更新的同时,把滚动高度同时往下滚动,就相当于没滚动