一、state
1、演示
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>state</title>
</head>
<body>
<div id="test"></div>
</body>
<script src="../js/react/react.development.js" type="text/javascript"></script>
<script src="../js/react/react-dom.development.js" type="text/javascript"></script>
<script src="../js/react/babel.min.js" type="text/javascript"></script>
<script type="text/babel">
class Weather extends React.Component {
constructor(props) {
super(props);
console.log("构造器调用了");
this.state = {
isHot: true,
wind: "微风",
};
this.changeWeather = this.changeWeather.bind(this);
}
render() {
console.log("render 方法调用了");
return (
<h1 id="title" onClick={this.changeWeather}>
今天天气很{this.state.isHot ? "炎热" : "凉爽"},{this.state.wind}
</h1>
);
}
changeWeather() {
console.log("changeWeather 方法调用了");
this.setState({ isHot: !this.state.isHot });
}
}
ReactDOM.render(<Weather />, document.getElementById("test"));
</script>
</html>
2、解读
- 解决 changeWeather 方法中 this 指向问题
js
this.changeWeather = this.changeWeather.bind(this);
1. 通过 Weather 实例调用 changeWeather 方法时,changeWeather 方法中的 this 就是 Weather 实例
2. 由于 changeWeather 方法作为 onClick 的回调,所以不是通过实例调用的,是直接调用
3. 类中的方法默认开启局部的严格模式,所以 changeWeather 方法中的 this 就是 undefined
- state 不可以直接更改,需要借助 setState 进行更新,且更新是通过合并方式,不是替换
js
this.setState({ isHot: !this.state.isHot });
- 构造器调用 1 次,render 方法调用 1 + n 次(1 是初始化的那次、n 是状态更新的次数),changeWeather 方法点几次调用几次
二、state 的简写方式
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>state 的简写方式</title>
</head>
<body>
<div id="test"></div>
</body>
<script src="../js/react/react.development.js" type="text/javascript"></script>
<script src="../js/react/react-dom.development.js" type="text/javascript"></script>
<script src="../js/react/babel.min.js" type="text/javascript"></script>
<script type="text/babel">
class Weather extends React.Component {
// 初始化状态
state = {
isHot: true,
wind: "微风",
};
// 自定义方法,要用赋值语句形式 + 箭头函数
changeWeather = () => {
console.log(this);
this.setState({ isHot: !this.state.isHot });
}
render() {
return (
<h1 id="title" onClick={this.changeWeather}>
今天天气很{this.state.isHot ? "炎热" : "凉爽"},{this.state.wind}
</h1>
);
}
}
ReactDOM.render(<Weather />, document.getElementById("test"));
</script>
</html>
三、props
1、演示
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>props</title>
</head>
<body>
<div id="test1"></div>
<div id="test2"></div>
<div id="test3"></div>
</body>
<script src="../js/react/react.development.js" type="text/javascript"></script>
<script src="../js/react/react-dom.development.js" type="text/javascript"></script>
<script src="../js/react/babel.min.js" type="text/javascript"></script>
<script type="text/babel">
class Person extends React.Component {
render() {
return (
<ul>
<li>姓名:{this.props.name}</li>
<li>性别:{this.props.sex}</li>
<li>年龄:{this.props.age}</li>
</ul>
);
}
}
ReactDOM.render(<Person name="tom" sex="男" age="18" />, document.getElementById("test1"));
ReactDOM.render(<Person name="jack" sex="男" age="20" />, document.getElementById("test2"));
const p = {
name: "smith",
sex: "男",
age: "25",
};
ReactDOM.render(<Person {...p} />, document.getElementById("test3"));
</script>
</html>
- 使用解构赋值
js
class Person extends React.Component {
render() {
const { name, sex, age } = this.props;
return (
<ul>
<li>姓名:{name}</li>
<li>性别:{sex}</li>
<li>年龄:{age}</li>
</ul>
);
}
}
- 注:props 是只读的
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>props 限制与注意事项</title>
</head>
<body>
<div id="test1"></div>
<div id="test2"></div>
</body>
<script src="../js/react/react.development.js" type="text/javascript"></script>
<script src="../js/react/react-dom.development.js" type="text/javascript"></script>
<script src="../js/react/babel.min.js" type="text/javascript"></script>
<script src="../js/react/prop-types.js" type="text/javascript"></script>
<script type="text/babel">
class Person extends React.Component {
render() {
const { name, sex, age } = this.props;
return (
<ul>
<li>姓名:{name}</li>
<li>性别:{sex}</li>
<li>年龄:{age + 1}</li>
</ul>
);
}
}
Person.propTypes = {
name: PropTypes.string.isRequired,
sex: PropTypes.string,
age: PropTypes.number,
speak: PropTypes.func,
};
Person.defaultProps = {
sex: "男",
age: 18,
};
ReactDOM.render(<Person name="tom" sex="男" age={18} speak={speak} />, document.getElementById("test1"));
ReactDOM.render(<Person name="jack" age={20} />, document.getElementById("test2"));
function speak() {
console.log("我说话了");
}
</script>
</html>
- 引入
prop-types,用于对组件标签属性进行限制
html
<script src="../js/react/prop-types.js" type="text/javascript"></script>
- 对 props 进行类型、必要性的限制
js
Person.propTypes = {
name: PropTypes.string.isRequired, // 限制 name 必传,且为字符串
sex: PropTypes.string, // 限制 sex 为字符串
age: PropTypes.number, // 限制 age 为数值
speak: PropTypes.func, // 限制 speak 为函数
};
- 指定 props 的默认值
js
Person.defaultProps = {
sex: "男", // 限制 sex 默认值为男
age: 18, // 限制 age 默认值为 18
};
四、props 的简写方式
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>props 的简写方式</title>
</head>
<body>
<div id="test1"></div>
<div id="test2"></div>
</body>
<script src="../js/react/react.development.js" type="text/javascript"></script>
<script src="../js/react/react-dom.development.js" type="text/javascript"></script>
<script src="../js/react/babel.min.js" type="text/javascript"></script>
<script src="../js/react/prop-types.js" type="text/javascript"></script>
<script type="text/babel">
class Person extends React.Component {
render() {
const { name, sex, age } = this.props;
return (
<ul>
<li>姓名:{name}</li>
<li>性别:{sex}</li>
<li>年龄:{age + 1}</li>
</ul>
);
}
static propTypes = {
name: PropTypes.string.isRequired, // 限制 name 必传,且为字符串
sex: PropTypes.string, // 限制 sex 为字符串
age: PropTypes.number, // 限制 age 为数值
speak: PropTypes.func, // 限制 speak 为函数
};
static defaultProps = {
sex: "男", // 限制 sex 默认值为男
age: 18, // 限制 age 默认值为 18
};
}
ReactDOM.render(<Person name="tom" sex="男" age={18} speak={speak} />, document.getElementById("test1"));
ReactDOM.render(<Person name="jack" age={20} />, document.getElementById("test2"));
function speak() {
console.log("我说话了");
}
</script>
</html>
五、类式组件中的构造器与 props
1、基本介绍
-
如果不想在构造器中通过 this 访问 props,可以不接收 props,不传递给 super(甚至不写构造器)
-
如果想要在构造器中通过 this 访问 props,必须要接收 props,并传递给 super
2、演示
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>类式组件中的构造器与 props</title>
</head>
<body>
<div id="test"></div>
</body>
<script src="../js/react/react.development.js" type="text/javascript"></script>
<script src="../js/react/react-dom.development.js" type="text/javascript"></script>
<script src="../js/react/babel.min.js" type="text/javascript"></script>
<script src="../js/react/prop-types.js" type="text/javascript"></script>
<script type="text/babel">
class Person extends React.Component {
render() {
const { name, sex, age } = this.props;
return (
<ul>
<li>姓名:{name}</li>
<li>性别:{sex}</li>
<li>年龄:{age + 1}</li>
</ul>
);
}
static propTypes = {
name: PropTypes.string.isRequired, // 限制 name 必传,且为字符串
sex: PropTypes.string, // 限制 sex 为字符串
age: PropTypes.number, // 限制 age 为数值
};
static defaultProps = {
sex: "男", // 限制 sex 默认值为男
age: 18, // 限制 age 默认值为 18
};
}
ReactDOM.render(<Person name="tom" sex="男" age={18} />, document.getElementById("test"));
</script>
</html>
- 接收 props,传递给 super
js
constructor(props) {
super(props);
console.log("constructor", this.props);
}
# 输出结果
constructor {name: 'tom', sex: '男', age: 18}
- 不接收 props,不传递给 super
js
constructor() {
super();
console.log("constructor", this.props);
}
# 输出结果
constructor undefined
- 接收 props,不传递给 super
js
constructor(props) {
super();
console.log("constructor", this.props);
}
# 输出结果
constructor undefined
六、函数式组件使用 props
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>函数式组件使用 props</title>
</head>
<body>
<div id="test"></div>
</body>
<script src="../js/react/react.development.js" type="text/javascript"></script>
<script src="../js/react/react-dom.development.js" type="text/javascript"></script>
<script src="../js/react/babel.min.js" type="text/javascript"></script>
<script src="../js/react/prop-types.js" type="text/javascript"></script>
<script type="text/babel">
function Person(props) {
const { name, sex, age } = props;
return (
<ul>
<li>姓名:{name}</li>
<li>性别:{sex}</li>
<li>年龄:{age + 1}</li>
</ul>
);
}
Person.propTypes = {
name: PropTypes.string.isRequired,
sex: PropTypes.string,
age: PropTypes.number,
};
Person.defaultProps = {
sex: "男",
age: 18,
};
ReactDOM.render(<Person name="tom" sex="男" age={18} />, document.getElementById("test"));
</script>
</html>