文章目录
前端之React学习(二)
state 状态
state 与 props 的区别
- props:组件对外的接口
- state:组件对内的接口
解释 - 组件内可以引用其他组件,组件之间的引用形成了一个树状的接口
如果下层组件需要引用上层组件的数据
上层组件就可通过下层组件中的 props 进行数据传递 - 组件除了使用上层组件传递的数据之外,它自身也有可能有需要管理的数据
这个对内管理的数据就是 state
state 与 props 最重要的区别
- state 是可变的
- props 对于当前页面的组件来说,他是只读,如果要修改,则修改传递给当前父组件的数据
声明式渲染
- React 中我们只需要关心的是数据,当数据改变的时候页面就会自动发生相应的改变
- 状态 state 等同于页面当中的数据,状态/数据改变了,页面中对应数据绑定的内容就会被 React 自动改变
state 的基本使用
不能使用无状态组件
// state 的基本使用
//在ES6中不管子类写不写constructor ,在new的实例时都会补上constructor
//但一旦写了constructor,一定要写上super() -----就是指向父类的构造方法
class Com extends React.Component {
constructor(props) {
super(props)
//定义 state
this.state = {
name: "嘻嘻"
}
}
render() {
// 修改state
// this.setState(key:newValue) 异步,react 自动触发render渲染
return (
<div>
<button onClick={() => { this.setState({ name: "哈哈" }) }}>改变state的name值</button>
<div>我是类组件-------{this.state.name}</div>
</div>
)
}
}
ReactDOM.render(<Com />, document.getElementById("demoReact"));
state 进阶
- this.setState()异步
- 字符串标签插入
class Com extends React.Component {
constructor(props) {
super(props)
this.state = {
name: "哈哈",
newHtml: "<div>我是标签中的内容</div>"
}
}
fun = () => {
this.setState({
name: "嘿嘿嘿"
},
() => {
console.log(this.state.name)
})
}
render() {
return (
<div>
<button onClick={this.fun}>点击修改state中的name</button>
{this.state.name}
<div>{this.state.newHtml}</div>
<div>{/* state 中字符串标签插入------dangerouslySetInnerHTML={__html:你要插入的字符串} */}</div>
<div dangerouslySetInnerHTML={{ __html: this.state.newHtml }}></div>
</div>
)
}
}
ReactDOM.render(<Com />, document.getElementById("demoReact"));
ref 转发
官方建议不要过度使用 ref,优先考虑 state
概念
- React 中提供了 ref 数据
- 表示当前组件的真正实例的引用,它会返回绑定当前属性
- 标识组件内的元素----方便我们查找
- 不能在无状态组件中使用,因为无状态组件无实例
ref 的三种使用方式
字符串的方式
//字符串方式
class Com extends React.Component {
fun = () => {
console.log(this.refs.demoInput.value)
}
render() {
return (
<div>
<p>我是组件</p>
<input type="text" placeholder="请输入" ref="demoInput" />
<button onClick={this.fun}>点我得到输入框的值</button>
</div>
)
}
}
ReactDOM.render(<Com />, document.getElementById("demoReact"))
回调函数(推荐)
就是在 dom 节点上或者组件上挂载函数,函数的入参即形参就是 dom 节点,他的效果跟字符串是一样的都是获取值的引用
//回调函数方式
class Com extends React.Component {
fun = () => {
console.log(this.textInput.value)
}
render() {
return (
<div>
<p>我是组件</p>
<input type="text" placeholder="请输入" ref={(input) => { this.textInput = input }} />
<button onClick={this.fun}>点我得到输入框的值</button>
</div>
)
}
}
ReactDOM.render(<Com />, document.getElementById("demoReact"))
React.createRef()
把值付给一个变量,通过 ref 挂载在节点或者组件上,使用 ref 的 current 属性拿到这个节点
//React.createRef方式
class Com extends React.Component {
constructor(props) {
super(props)
this.myRef = React.createRef()
}
fun = () => {
console.log(this.myRef.current.value)
}
render() {
return (
<div>
<p>我是组件</p>
<input type="text" placeholder="请输入" ref={this.myRef} />
<button onClick={this.fun}>点我得到输入框的值</button>
</div>
)
}
}
ReactDOM.render(<Com />, document.getElementById("demoReact"));
事件与 this
特点
- react 绑定事件使用的是小驼峰命名法
- 在绑定函数的时候不能加()------函数会立即执行
修改 this 指向
-
bind 方式原的绑定
-
函数通过箭头含数进行创建
-
consternation 提前绑定
-
把事件的调用写成箭头函数的调用方式
函数参数传递
事件对象传递
class Com extends React.Component {
constructor(props) {
super(props)
this.fun3 = this.fun3.bind(this)
}
fun1() {
console.log(this)
}
fun2 = () => {
console.log(this)
}
fun3() {
console.log(this)
}
fun4() {
console.log(this)
}
fun5(e) {
console.log(this)
console.log(e)
}
render() {
return (
<div>
我是一个组件
<button onClick={this.fun1.bind(this)}>bind方式调用</button>
<button onClick={this.fun2}>箭头函数绑定</button>
<button onClick={this.fun3}>提前绑定</button>
<button onClick={() => { this.fun4() }}>调用方式为箭头函数</button>
<div>函数参数的传递</div>
<button onClick={this.fun5.bind(this, "我是参数1")}>点我传参</button>
<button onClick={() => { this.fun5("我是参数2") }}>点我传参</button>
<div>传递事件对象</div>
<button onClick={(e) => { this.fun5("我是参数3", e) }}>点我传事件对象</button>
</div>
)
}
}
ReactDOM.render(<Com />, document.getElementById("demoReact"));
条件渲染
定义
根据状态的变化只渲染其中的一部分
实现
if 语句
注意jsx 中不允许用 if 语句
三元运算符
- if 和三元运算符例子
// 条件渲染
class Com extends React.Component {
constructor(props) {
super(props)
this.state = {
bool: true,//bool的值控制是否改变
}
}
fun() {
this.setState({
bool: !this.state.bool
})
}
render() {
let text;
let text1;
// if语句
if (this.state.bool) {
text = "你好"
} else {
text = "你坏"
}
return (
<div>
我是一个组件
<button onClick={this.fun.bind(this)}>点击修改</button>
<p>if语句:{text}</p>
<p >三元运算符:{this.state.bool ? "哎呀" : "呵呵"}</p>
</div>
)
}
}
ReactDOM.render(<Com />, document.getElementById("demoReact"));
state 状态提升
概念
- 多个组件需要反应相同的变化数据,提升到他们最近的一个父组件中
- 多个子组件需要利用到对方状态的情况下,需要使用状态提升
// 状态提升
class Com1 extends React.Component {
render() {
return (
<div>我是子组件1------{this.props.text}</div>
)
}
}
class Com2 extends React.Component {
render() {
return (
<div>我是子组件2------{this.props.text}</div>
)
}
}
class Com extends React.Component {
constructor(props) {
super(props)
this.state = {
comtext: "我是2个子组件都想要的数据"
}
}
fun = () => {
this.setState({
comtext: "修改数据"
})
}
render() {
return (
<div>
<div>我是父组件</div>
<button onClick={this.fun}>修改数据</button>
<Com1 text={this.state.comtext} />
<Com2 text={this.state.comtext} />
</div>
)
}
}
ReactDOM.render(<Com />, document.getElementById("demoReact"));