组件的三大核心属性
state
state
state
是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)
类式组件示例
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
class Timer extends React.Component {
// 初始化状态,这里的状态就是当前的秒数
constructor(props) {
super(props);
// state初始化,这里可以直接使用 = 初始化
this.state = {seconds: 0};
}
// 定义tick方法,用于给秒数+1
// 注意: 状态数据只能调用setState方法更新,不可以直接操作
// 3. 让自定义函数在构造器中初始化bind() 从而绑定this
tick() {
this.setState(state => ({
seconds: state.seconds + 1
}));
}
// 组件被挂载时,启用interval
componentDidMount() {
// 注意,这里的this对象是当前组件的实例
// 自定义方法中this对象为undefined,解决办法有:
// 1. 箭头函数
// this.interval = setInterval(() => this.tick(), 1000);
// 2. 强制绑定this: 通过函数对象的bind()
this.interval = setInterval(function () {
this.tick();
}.bind(this), 1000);
}
// 组件被移除时,停止interval
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<div>
Seconds: {this.state.seconds}
</div>
);
}
}
ReactDOM.render(
<Timer/>,
document.getElementById('app')
);
</script>
</body>
</html>
函数式组件示例(hooks)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
function Timer() {
// 定义状态,返回当前状态值以及设置状态函数
const [seconds, setSeconds] = React.useState(0);
// Effect 影响、副作用
// 是componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合
// 用于告诉 React 组件需要在渲染后执行某些操作
// useEffect 会在每次渲染后都执行
React.useEffect(() => {
let interval = setInterval(function () {
setSeconds(seconds + 1);
}.bind(this), 1000);
// 返回可选的清除函数
return function () {
clearInterval(interval);
}
});
return (<div>
Seconds: {seconds}
</div>);
}
ReactDOM.render(
<Timer/>,
document.getElementById('app')
);
</script>
</body>
</html>
注意:
组件中render方法中的this为组件实例对象
组件自定义的方法中this为undefined,如何解决?
强制绑定this: 通过函数对象的bind()
箭头函数
状态数据,不能直接修改或更新
props
props
就像HTML标签的属性。
每个组件对象都会有props(properties的简写)属性
组件标签的所有属性都保存在props中
每个props都是只读的
作用:
通过标签属性从组件外向组件内传递变化的数据
注意: 组件内部不要修改props数据
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
class Person extends React.Component {
render() {
return (
<ul>
<li>姓名:{this.props.name}</li>
<li>年龄:{this.props.age}</li>
<li>性别:{this.props.sex}</li>
</ul>
);
}
}
ReactDOM.render(
<Person name="张三" age="12" sex="男"/>,
document.getElementById('app')
);
</script>
</body>
</html>
...
批量传递props
...
批量传递props下面的代码与上面的代码相同。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
class Person extends React.Component {
render() {
return (
<ul>
<li>姓名:{this.props.name}</li>
<li>年龄:{this.props.age}</li>
<li>性别:{this.props.sex}</li>
</ul>
);
}
}
const p = {name: "张三", age: "12", sex: "男"};
ReactDOM.render(
<Person {...p}/>,
document.getElementById('app')
);
</script>
</body>
</html>
对props进行限制
对上述组件的props
添加指定的规则:
name
必传,且必须为字符串age
可选,但是必须为数字类型,并给默认值0sex
可选,并给默认值男
15版本的React,直接使用React.PropTypes.string
,在16版本,需要引入新的prop-types.js
模块:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://unpkg.com/prop-types@15.6/prop-types.min.js"></script>
<script type="text/babel">
class Person extends React.Component {
render() {
return (
<ul>
<li>姓名:{this.props.name}</li>
<li>年龄:{this.props.age}</li>
<li>性别:{this.props.sex}</li>
</ul>
);
}
}
// 定义Person组件的props的属性规则
Person.prototype = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
}
// 默认属性值
Person.defaultPrototype = {
age: 0,
sex: "男",
}
ReactDOM.render(
<Person name="张三" age={12} sex={"男"}/>,
document.getElementById('app')
);
</script>
</body>
</html>
或者将规则写到类内部:
class Person extends React.Component {
static prototype = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
}
static defaultPrototype = {
age: 0,
sex: "男",
}
render() {
return (
<ul>
<li>姓名:{this.props.name}</li>
<li>年龄:{this.props.age}</li>
<li>性别:{this.props.sex}</li>
</ul>
);
}
}
函数式组件使用props
props
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://unpkg.com/prop-types@15.6/prop-types.min.js"></script>
<script type="text/babel">
function Person(props){
return (
<ul>
<li>姓名:{props.name}</li>
<li>年龄:{props.age}</li>
<li>性别:{props.sex}</li>
</ul>
);
}
// 定义Person组件的props的属性规则
Person.prototype = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
}
// 默认属性值
Person.defaultPrototype = {
age: 0,
sex: "男",
}
ReactDOM.render(
<Person name="张三" age={12} sex={"男"}/>,
document.getElementById('app')
);
</script>
</body>
</html>
refs
refs
类似选择器,可以给标签增加ref属性,并通过this.refs
、回调等形式,获取到指定的元素。
字符串形式的ref
(废弃)
ref
(废弃)<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://unpkg.com/prop-types@15.6/prop-types.min.js"></script>
<script type="text/babel">
class Bt extends React.Component {
render() {
return (
<div>
<input type="text" ref="content"/>
<button onClick={this.sayHello}>获取内容</button>
</div>
);
}
sayHello = () => {
let {content} = this.refs;
console.log(this.refs)
alert(content.value);
}
}
ReactDOM.render(<Bt/>, document.getElementById("app"))
</script>
</body>
</html>
字符串类型的
ref
效率有问题,会在未来的版本中移除
回调形式的ref
ref
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://unpkg.com/prop-types@15.6/prop-types.min.js"></script>
<script type="text/babel">
class Bt extends React.Component {
render() {
return (
<div>
<input type="text" ref={(currentNode) => {this.input1 = currentNode}}/>
<button onClick={this.sayHello}>获取内容</button>
</div>
);
}
sayHello = () => {
alert(this.input1.value);
}
}
ReactDOM.render(<Bt/>, document.getElementById("app"))
</script>
</body>
</html>
crateRef()
推荐
crateRef()
推荐<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://unpkg.com/prop-types@15.6/prop-types.min.js"></script>
<script type="text/babel">
class Bt extends React.Component {
contentRef = React.createRef()
render() {
return (
<div>
<input type="text" ref={this.contentRef}/>
<button onClick={this.sayHello}>获取内容</button>
</div>
);
}
sayHello = () => {
console.log(this.contentRef);
alert(this.contentRef.current.value);
}
}
ReactDOM.render(<Bt/>, document.getElementById("app"))
</script>
</body>
</html>
构造器
在React中,构造的主要作用有两个:
给
state
初始化为事件处理函数绑定实例
如果需要
props
,那么一定要重写默认构造,并调用super(props)
,否则可能会出现undefined
错误
ss://YWVzLTI1Ni1nY206ZmFCQW9ENTRrODdVSkc3@134.195.198.95:2375#github.com/freefq%20-%20%E5%8C%97%E7%BE%8E%E5%9C%B0%E5%8C%BA%20%2037
最后更新于
这有帮助吗?