认识React
- React是用于构建用户界面的JavaScript库,起源于Facebook的内部项目,因为该公司对市场上所有 JavaScript MVC框架,都不满意,就决定自己写一套,用来架设Instagram的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了.
- 框架用途
React主要用于构建UI。你可以在React里传递多种类型的参数,如声明代码,帮助你渲染出UI、也可以是静态的HTML DOM元素、也可以传递动态变量、甚至是可交互的应用组件。 - 框架特点
- 声明式设计:React采用声明范式,可以轻松描述应用。
- 高效:React通过对DOM的模拟,最大限度地减少与DOM的交互。
- 灵活:React可以与已知的库或框架很好地配合。
<!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>初识React</title>
<!-- 引入react reactDOM 以及babel -->
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.development.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
</body>
<script type="text/babel">
const dom = <h1>hello world React</h1>;
ReactDOM.render(dom, document.getElementById("app"));
</script>
</html>
React组件
<!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>初识React</title>
<!-- 引入react reactDOM 以及babel -->
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.development.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
</body>
<!-- 注意这里的type的写法 -->
<script type="text/babel">
//Demo组件 函数式组件
function Demo() {
// 此处的this是undefined,因为babel编译成严格模式了
console.log(this);
return <h1>我是demo组件</h1>;
}
// // 类组件
class Com extends React.Component {
render() {
return <h1>类组件</h1>;
}
}
ReactDOM.render(<Com/>, document.getElementById("app"));
</script>
</html>
React三大属性
为了避免与原生事件名冲突,React内部重写了方法名:onclick --> onClick
一、state的使用以及注意事项
<!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>初识React</title>
<!-- 引入react reactDOM 以及babel -->
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.development.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- 对props进行限制 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.0/prop-types.js"></script>
</head>
<body>
<div id="app"></div>
</body>
<script type="text/babel">
// class Weather extends React.Component {
// constructor(props) {
// super(props);
// this.state = {
// isHot: true,
// };
// }
// changeWeather(params) {
// console.log(`click me`);
// //React中的状态不可以直接更改
// // this.state.isHot = !isHot
// // 状态必须通过setState进行修改
// const isHot = this.state.isHot
// this.setState({isHot:!isHot})
// }
// render() {
// return (
// <h1 onClick={this.changeWeather.bind(this)}>
// 今天天气{this.state.isHot ? "很热" : "很冷"}
// </h1>
// );
// }
// }
// 精简代码
class Weather extends React.Component {
state = {
isHot: true,
};
changeWeather = (params) => {
const isHot = this.state.isHot;
this.setState({ isHot: !isHot });
};
render() {
return (
<h1 onClick={this.changeWeather}>
今天天气{this.state.isHot ? "很热" : "很冷"}
</h1>
);
}
}
ReactDOM.render(<Weather />, document.getElementById("app"));
</script>
</html>
注意事项
- 不要直接修改 State
//此代码不会重新渲染组件:
// Wrong
this.state.comment = 'Hello';
//而是应该使用 setState():
// Correct
this.setState({comment: 'Hello'});
- State 的更新可能是异步的,出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。
因为 this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
//此代码可能会无法更新计数器:
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
//要解决这个问题,可以让 setState() 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
//上面使用了箭头函数,不过使用普通的函数也同样可以:
// Correct
this.setState(function(state, props) {
return {
counter: state.counter + props.increment
};
});
- State 的更新会被合并
//当你调用 setState() 的时候,React 会把你提供的对象合并到当前的 state。
//例如,你的 state 包含几个独立的变量:
constructor(props) {
super(props);
this.state = {
posts: [],
comments: []
};
}
//然后你可以分别调用 setState() 来单独地更新它们:
componentDidMount() {
fetchPosts().then(response => {
this.setState({
posts: response.posts
});
});
fetchComments().then(response => {
this.setState({
comments: response.comments
});
});
}
//这里的合并是浅合并,所以 this.setState({comments}) 完整保留了 this.state.posts, 但是完全替换了 this.state.comments。
二、Props
<script type="text/babel">
//类组件中的props
class Person extends React.Component {
state = {};
// 限制props的数据类型
static propTypes = {
name: PropTypes.string,
age: PropTypes.number,
};
// props的默认值
static defaultProps = {
sex: '男',
};
render() {
let { name, age, sex } = this.props;
return (
<ul>
<li>姓名:{name}</li>
<li>性别:{sex}</li>
<li>年龄:{age}</li>
</ul>
);
}
}
// 函数式组件中的props
/* function Person(props){
console.log(props);
let {age,name,sex} = props
return (
<ul>
<li>{age}</li>
<li>{name}</li>
<li>{sex}</li>
</ul>
)
}
// 函数式组件没有static,只能写在外面
// 限制props的数据类型
Person.propTypes = {
name: PropTypes.string,
age: PropTypes.number,
};
// props的默认值
Person.defaultProps = {
sex: '男',
}; */
// const person = { name: "张三", sex: "女", age: 22 };
const person = { name: "张三", age: 22 };
ReactDOM.render(<Person {...person} />, document.getElementById("app"));
</script>
三、refs
<script type="text/babel">
//1 ref的字符串形式
/* class Person extends React.Component {
state = {};
// 点击按钮显示左侧输入框的内容
showData = ()=>{
const {input1} = this.refs
console.log(input1.input1.value);
}
// 失去焦点显示右侧输入框的内容
showData2 = ()=>{
console.log('失去焦点');
}
render() {
let { name, age, sex } = this.props;
return (
<div>
<input ref = 'input1' type="text" placeholder='点击按钮提示数据'/>
<button onClick={this.showData}>点我和返回显示左侧的数据</button>
<input onBlur = {this.showData2} type="text" placeholder='失去焦点提示数据' />
</div>
);
}
} */
//2 ref的回调函数的写法
class Person extends React.Component {
state = {
ishot: false,
};
// 点击按钮显示左侧输入框的内容
showData = () => {
// 这时就不能从refs上拿input1了
const { input1 } = this;
};
saveInput1 = (c)=>{
// 这种写法页面刷新的时候不会打印两遍
console.log('@',c)
}
// 失去焦点显示右侧输入框的内容
showData2 = () => {
console.log("失去焦点");
};
changeWeather = () => {
let { ishot } = this.state;
this.setState({
ishot: !ishot,
});
};
render() {
let { name, age, sex } = this.props;
const { ishot } = this.state;
return (
<div>
<h1>今天天气很{ishot ? "炎热" : "冷"}</h1>
<button onClick={this.changeWeather}>切换天气</button>
<br />
{/* <input
ref={(currentNode) => {
this.input1 = currentNode;
// 内联式写法页面刷新的时候会打印两遍
console.log("@", currentNode);
}}
type="text"
placeholder="点击按钮提示数据"
/> */}
<input
ref={this.saveInput1}
type="text"
placeholder="点击按钮提示数据"
/>
<button onClick={this.showData}>点我和返回显示左侧的数据</button>
<input
onBlur={this.showData2}
type="text"
placeholder="失去焦点提示数据"
/>
</div>
);
}
}
//3 ref的createRef 详细官网了解
// const person = { name: "张三", sex: "女", age: 22 };
const person = { name: "张三", age: 22 };
ReactDOM.render(<Person {...person} />, document.getElementById("app"));
</script>