react框架基础
react 框架基础
1. 声明式渲染
<!-- react 的核心库 -->
<script src="./libs/react.development.js"></script>
<!-- 提供与DOM相关的功能 -->
<script src="./libs/react-dom.development.js"></script>
<!-- babel编译器,转码器,主要负责把react中的代码, 现代浏览器不能直接运行,需要转换.生产环境中不建议使用-->
<script src="./libs/babel.min.js"></script>
</head>
<body>
<!-- 2. 创建容器,用来渲染其他元素或将来封装的组件 -->
<div id="app"></div>
<!-- 3. 实现:就是通过引入的脚本在容器中渲染其他元素或组件 -->
<!-- jsx语法中的注释,jsx语法中的插值语法 -->
<script type="text/babel">
let element = (
// 单根元素
<div>
{/*这才是注释,两个花括号是插值语法*/}
{1+1}-{true?"成立":"不成立"}
</div>
)
ReactDOM.render(element,document.querySelector("#app"))
</script>
</body>
2. 组件封装(函数组件,类组件)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
// 1。函数组件
function Login() {
// 返回视图,视图用啥定义?jsx
return (
<div>
{/*标签必须正确闭合*/}
{/*for在js中是关键字,使用htmlFor, class=>className*/}
<label htmlFor="acc" className="red">
账号
</label>
<input type="text" id="acc" />
<br />
<input type="password" />
<br />
<button>登录</button>
</div>
);
}
// 2。类组件
class Login2 extends React.Component {
// 渲染函数
render() {
return (
<div>
{/*标签必须正确闭合*/}
{/*for在js中是关键字,使用htmlFor, class=>className*/}
<label htmlFor="acc" className="red">
账号2
</label>
<input type="text" id="acc" />
<br />
<input type="password" />
<br />
<button>登录</button>
</div>
);
}
}
ReactDOM.render(<Login2></Login2>, document.querySelector("#app"));
</script>
</body>
</html>
3.父子组件传值
<body>
<div id="app"></div>
<script type="text/babel">
// props 接收父组件传递的数据
function Person(props) {
return (
<div>
{/*
<p>名称:{props.name}</p>
<p>年龄:{props.age}</p>
<p>性别:{props.sex}</p>
*/}
<p>名称:{props.person.name}</p>
<p>年龄:{props.person.age}</p>
<p>性别:{props.person.sex}</p>
</div>
);
}
class Person2 extends React.Component {
render(props) {
// console.log(this);
let { name, age, sex } = this.props.person;
return (
<div>
{/*
<p>名称:{this.props.person.name}</p>
<p>年龄:{this.props.person.age}</p>
<p>性别:{this.props.person.sex}</p>
*/}
<p>名称:{name}</p>
<p>年龄:{age}</p>
<p>性别:{sex}</p>
</div>
);
}
}
let zs = { name: "张三", age: 16, sex: "男" };
ReactDOM.render(
// <Person name="张三" age="18" sex="男" />,
// react没有指令.使用插值语法绑定动态值
<Person person={zs} />,
document.querySelector("#app")
);
</script>
</body>
4.类组件事件绑定,双向数据绑定,定义更改数据
<body>
<div id="app"></div>
<script type="text/babel">
class Login extends React.Component {
// 类的构造函数
constructor() {
// 在本类Login调用super()超类,相当于去调用父类React.Component的构造函数。
// 为啥? 类实例化时有一个顺序,进入时 Login->React.Component,执行时React.Component->Login
super();
// 设置数据
this.state = {
account: "admin2",
password: "111111",
};
// 2。事件绑定
// 在构造函数中使用bind纠正this, 让myLogin()方法中的this指向当前组件
this.abc = this.myLogin.bind(this);
}
// 这样也可以设置数据
/* state = {
account: "admin",
password: "123456",
}; */
// 渲染函数
render() {
return (
<div>
<p>事件绑定的两种方式:</p>
<p>1. 直接定义箭头函数,视图中直接调用箭头函数</p>
<p>2. 定义成类的方法,在构造函数中定义一个属性,初始化成方法,并纠正this指向,在视图中调用构造函数中的属性。</p>
<p>双向数据绑定:</p>
<p>开发者自行控制value属性和change事件</p>
<p>注意事件对象的使用</p>
<p>在类组件中定义数据的方式</p>
<p>1. 在构造函数中,如this.state=xxx</p>
<p>2. 直接在类中定义属性 state=xxx</p>
<p>3. setState()来更改state</p>
{/*标签必须正确闭合*/}
{/*for在js中是关键字,使用htmlFor, class=>className*/}
<label htmlFor="acc" className="red">
账号:{this.state.account}
</label>
{/*
react中没有指令,所以v-model这种用法不能实现,需要开发者手动控制value和onchange事件
在react框架中实现双向数据绑定需要手动控制value和onchange事件。
事件名称格式, onchange=>onChange onclick=>onClick
*/}
<input
type="text"
id="acc"
value={this.state.account}
onChange={this.changeAccount}
/>
<br />
<label htmlFor="pwd" className="red">
密码:{this.state.password}
</label>
{/*不建议在视图中直接编写业务逻辑。*/}
<input
type="password"
id="pwd"
value={this.state.password}
onChange={(e) => {
this.setState({ password: e.target.value });
}}
/>
<br />
<button onClick={this.abc}>登录</button>
</div>
);
}
myLogin(){
// 注意this指向
console.log(this.state.account)
}
// 1. 绑定事件 使用箭头函数
// e=>event事件对象,通过事件对象可以拿到操作的元素(目标元素)
changeAccount = (e) => {
console.log(e.target.value);
// this.state.account = e.target.value; // 错误的写法
// setState()就react看唯一一种更改state数据的方式。且支持响应式。
this.setState({
account: e.target.value,
});
};
}
ReactDOM.render(<Login />, document.querySelector("#app"));
</script>
</body>
5.自定义属性, 操作style,class
<style>
.red{
color: red
}
</style>
<body>
<div id="app"></div>
<script type="text/babel">
// 函数组件中如何定义数据??使用hook
function Com1(props) {
console.log(props);
let style = { border: "1px solid red", fontSize: 20 };
let red = "red"
return (
<div style={style} className={red}>
<div>自定义</div>
</div>
);
}
ReactDOM.render(
<Com1 data-dsh="dong shu hua" dsh="董书华" />,
document.querySelector("#app")
);
</script>
</body>
6.生命周期,循环
<div id="app"></div>
//products.json
{
"products": [
{"id": 1, "name": "苹果手机", "price": 8000},
{"id": 2, "name": "华为手机", "price": 8000}
]
}
<script type="text/babel">
class ProductList extends React.Component {
render() {
console.log("render渲染函数执行,也是一个生命周期");
/* return (
<div className="product">
{
this.state.products.map((p) => {
return <div className="item" key={p.id}>{p.id}-{p.name}-{p.price}</div>;
})
}
</div>
); */
/* let lists = [];
for (let i = 0; i < this.state.products.length; i++) {
const p = this.state.products[i];
let item = <div className="item" key={p.id}>{p.id}-{p.name}-{p.price}</div>;
lists.push(item)
} */
/* let lists = this.state.products.map((p) => (
<div className="item" key={p.id}>
{p.id}-{p.name}-{p.price}
</div>
)); */
let lists = [];
this.state.products.forEach((p) => {
let item = (
<div className="item" key={p.id}>
{p.id}-{p.name}-{p.price}
</div>
);
lists.push(item);
});
return <div className="product">{lists}</div>;
}
// 组件的数据
state = {
products: [], //存储商品列表
};
// 生命周期,相当于vue中的mounted
componentDidMount() {
console.log("componentDidMount执行。");
this.getProducts();
}
async getProducts() {
let result = await window
.fetch("data/products.json")
.then((res) => res.json());
console.log(result);
this.setState({
products: result.products,
});
}
}
ReactDOM.render(<ProductList />, document.querySelector("#app"));
</script>
7.生命周期
<script type="text/babel">
class Com1 extends React.Component {
// props用来接收外部传递的数据
constructor(props) {
console.log("1。构造函数中,初始化props和state");
// 初始化外部传递的数据props
super(props);
// 初始化组件自身的数据state
this.state = {
products:[],
count: 1,
};
}
render() {
console.log("3。render渲染函数,数据发生变化render重新执行");
return (
<div>
<p>生命周期</p>
<p>{this.state.count}</p>
<button onClick={this.add}>累加</button>
</div>
);
}
add = ()=>{
this.setState({
count: this.state.count+1
})
}
// 相当于vue中的beforeMount, component组件, will即将,mount渲染,准备好。
// 警告:componentWillMount has been renamed, and is not recommended for use
componentWillMount() {
console.log("2。组件渲染前执行,可以在此处拉取数据");
this.setState({
products: [1, 2, 3],
});
}
componentDidMount() {
console.log("4。组件渲染后执行,可以在此处拉取数据");
}
componentWillUpdate(){
console.log("5。数据更新前执行")
}
componentDidUpdate(){
console.log("6。数据更新后执行")
}
shouldComponentUpdate(){
// 一般通过在sholdComponentUpdate生命周期中返回False,减少render函数的执行,从而达到渲染性能的提升。
// 一般使用在视图中不使用数据state|props的情况下。
console.log("4.5。shouldComponentUpdate返回一个布尔值,返回true,让组件更新,返回false不让组件更新")
return false
}
// 相当于vue中的beforeDestory()。用来清楚定时器,window全局事件。如:window.onscoll
componentWillUnMount(){
console.log("组件消毁前执行。")
}
}
ReactDOM.render(<Com1 />, document.querySelector("#app"));
</script>
8.生命周期
<script type="text/babel">
class BigCom extends React.Component {
state = {
name: 'hello'
}
render() {
return (
<div>
<h1>大组件</h1>
<button onClick={this.changeName}>更新dsh</button>
<Com dsh={this.state.name} />
</div>
);
}
changeName=()=>{
this.setState({
name: "HELLO"
})
}
}
class Com extends React.Component {
constructor(props){
console.log("1.构造函数")
super(props)
}
render() {
console.log("2.渲染函数")
return (
<div>
<h1>小组件{this.props.dsh}</h1>
</div>
);
}
// Warning: componentWillReceiveProps has been renamed, and is not recommended for use
// 推荐使用componentDidUpdate
/* componentWillReceiveProps(){
console.log("即将接收props时执行")
} */
componentWillUpdate(){
console.log("数据state|props发生变化前执行")
}
componentDidUpdate(){
console.log("数据state|props发生变化后执行")
}
}
ReactDOM.render(<BigCom />, document.querySelector("#app"));
</script>
9.阻止默认行为
<script type="text/babel">
class Com extends React.Component {
render() {
let html = { __html: '<a href="javascript:void(0);">百度</a>' };
return (
<div>
<a href="https://www.baidu.com">百度</a>
<br />
{/*v-html和v-text*/}
<div dangerouslySetInnerHTML={html}></div>
<form action="https://www.sina.com.cn" onSubmit={this.submit}>
<input type="text" />
<button>提交</button>
</form>
{/*alt必写,不写时在脚手架中报错*/}
<img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" alt="" />
</div>
);
}
go = () => {
location.href = "https://www.baidu.com";
};
submit = (e)=>{
e.preventDefault();
console.log("e.preventDefault()可以阻止form的默认行为")
}
}
ReactDOM.render(<Com />, document.querySelector("#app"));
</script>

浙公网安备 33010602011771号