React类组件是通过创建 class 继承 React.Component创建的。类组件中通过render函数返回react元素。react组件的三大核心属性是建立在react的类组件基础上的,即:state、props、refs。
一、state
概念
state是组件对象最重要的属性,值是对象(可以包含多个key:value的组合),组件被称为"状态机",通过更新组件的state来更新对应的页面显示(重新渲染组件),有state称为复杂组件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>State</title>
<!-- 引入react核心库 -->
<script src="https://cdn.bootcdn.net/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<!-- 引入操作dom的扩展库 -->
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
<!-- 引入babel来解析jsx语法 -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class Content extends React.Component {
//state:定义当前组件内部的状态,状态是当前组件私有的
state = {
content: "React真好用",
count: 0,
isHot: true,
};
render() {
const { content, isHot, count } = this.state;
return (
<div>
<h1>State</h1>
<p>{content}</p>
<p>{count}</p>
<p>{isHot ? "热啊" : "冷啊"}</p>
</div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(<Content />);
</script>
</body>
</html>
执行结果如下:
如何修改state的值
-
不可以直接通过this.state.xxx=xxx的方式修改state对象的内容。
-
修改state一定要调用setState这个方法去修改。
-
使用语法:setState({key:value})。
-
setState做了两件事:1. 改变state 2. 重新调用了一次render。
<div id="app"></div>
<script type="text/babel">
class Demo extends React.Component {
state = {
isHot: true,
};
render() {
const { isHot } = this.state;
return (
<div>
<p>今天天气很{isHot ? "很热" : "凉快"}</p>
<button onClick={this.changeWea}>修改天气</button>
</div>
);
}
/*
state不能直接修改,需要使用组件实例的setState方法
setState接受的参数是一个对象,将来会合并给原有的state中
*/
changeWea = () => {
const { isHot } = this.state;
// this.state.isHot = false; XXX
this.setState({ isHot: !isHot });
};
}
const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(<Demo />);
</script>
执行结果如下:
二、props
概念
-
props就是组件定义属性的集合,它是组件对外的接口,由外部通过JSX属性传入设置(也就是从外部传递给内部组件的数据)。
-
每个组件对象都会有props(properties的简写)属性。
-
组件标签的所有属性都保存在props中。
作用
1.通过标签属性从组件外向组件内传递变化的数据,外部世界(组件)就是通过prop来和组件进行对话数据传递的。
2.组件内部不要修改props数据,props是只读的。
<script type='text/babel'>
class Myself extends React.Component{
render(){
console.log(this.props);
let {name,age,sex} = this.props.mes
//如果真的要修改props 则可以解构出来某个属性 然后对变量进行修改
name+="~"
return (
<ul>
<li>姓名是{name}</li>
<li>性别是{sex}</li>
<li>年龄是{age}</li>
</ul>
)
}
}
class App extends React.Component{
state = {
persons:[
{name:"laowang",age:19,sex:"man"},
{name:"laoli",age:29,sex:"man"},
{name:"laowan",age:12,sex:"woman"},
]
}
render(){
console.log(this);
const {persons} = this.state;
return (
<div>
{
persons.map((item,index)=>{
return <Myself mes={item} key={index}/>
})
}
</div>
)
}
}
const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(<App />);
</script>
批量传递props
当需要把一个对象内所有的key-value都传递到组件中,可以使用批量传递。比如一个对象obj,我们可以在传递props的时候直接书写为{...obj}即可。当然,我们可以传递额外的props来添加和修改批量传递的内容。
return (
<div>
{
persons.map((item,index)=>{
// return <Myself name={item.name} sex={item.sex} age={item.age} key={index}/>
//{...o}在jsx中书写时,可以展开对象为key-value(jsx+react实现的 不是js语法)
return <Myself {...item} key={index}/>
})
}
</div>
)
执行结果如下:
配置props限制
1.引入react的propType.js第三方包。
<!-- 对props中数据类型进行检测及限制 -->
<script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.8.1/prop-types.js"></script>
2.prop-types的主要作用:对props中数据类型进行检测及限制
3.propType的使用:
-
给组件扩展静态属性propTypes,值是一个对象。
-
key就是被限制的props属性。
-
value值的写法:可以限制值的数据类型(number、string、bool、func、object、array等)PropTypes.XXXX;限制特定的内容:PropTypes.oneOf(['a', 'b']),值只能是a或者b;也可以在任何 PropTypes 属性后面加上 isRequired 后缀,这样如果这个属性父组件没有提供时,会打印警告信息。
<script type="text/babel">
class Myself extends React.Component {
render() {
console.log(this.props);
const { name, age, nicknames, address } = this.props;
return (
<div>
<h1>我是:{name}</h1>
<p>我今年:{age}岁</p>
<ul>
{nicknames.map((item, index) => {
return <li key={index}>{item}</li>;
})}
</ul>
<p>我家住在{address}</p>
</div>
);
}
static propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
nicknames: PropTypes.array,
address: PropTypes.oneOf(["湖北", "湖南"]),
};
}
class App extends React.Component {
render() {
return (
<div>
<Myself
name="李红"
age={18}
nicknames={["小红", "lucy", "普罗"]}
address="湖北"
/>
</div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(<App />);
</script>
执行结果如下:
三、refs
概念
Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素。
ref的字符串方法
只需要在被获取的DOM上设置ref属性 值为一个自定义名称XXX,在当前组件的其他位置可以通过this.refs.XXX获取当前DOM。
<script type="text/babel">
class App extends React.Component {
render() {
return (
<div>
<input type="text" ref="oIpt" />
<button onClick={this.showMsg}>点我弹出input中输入的内容</button>
</div>
);
}
showMsg = () => {
console.log(this.refs.oIpt.value);
};
}
const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(<App />);
</script>
执行结果如下:
回调函数形式的ref
1.ref属性的值是一个函数(箭头函数)。
2.当读到ref属性的时候,react会当内部的函数调用,并传递当前的DOM为实参。
3.把这个接受实参的形参赋值给实例对象的一个属性,这个属性就是被获取的DOM。
<script type="text/babel">
class App extends React.Component {
render() {
console.log(this);
return (
<div>
<input type="text" ref={(c) => (this.oIpt = c)} />
<button onClick={this.showMsg}>点我弹出input中输入的内容</button>
</div>
);
}
showMsg = () => {
console.log(this.oIpt.value);
};
}
const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(<App />);
</script>
createRef的使用
1.首先使用React.createRef()方法创建一个容器。
2.把这个容器给到被获取的DOM节点的ref属性上。
3.通过this.容器.current获取到当前的DOM。
<script type="text/babel">
class App extends React.Component {
//设置一个ref的容器
oIpt = React.createRef();
render() {
console.log(this);
return (
<div>
<input type="text" ref={this.oIpt} />
<button onClick={this.showMsg}>点我弹出input中输入的内容</button>
</div>
);
}
showMsg = () => {
alert(this.oIpt.current.value);
};
}
const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(<App />);
</script>
总结
以上就是对react组件对象的三大核心属性的一个简单的演示。
简单的理解state就是状态,保存状态数据的属性,用来拿到状态数据对界面进行渲染,因为state是响应式的,所以向state中存放状态数据时需要使用setState方法进行更改,react会重新调用render函数进行渲染。
而props就可以理解为标签中的属性,通过props就可以读取组件外向组件内传递的数据。
refs就是组件用来标识自己的一个标志,通过这个属性就可以拿到标签的信息,比如value,但注意,字符串形式的ref官方已经不建议使用它,因为 string 类型的 refs 已过时并可能会在未来的版本被移除。