react-入门
1.安装脚手架工具
sudo cnpm install -g create-react-app
2.创建项目文件
create-react-app my-app
3.运行项目
npm startcreate-react-app脚手架的命令: 启动一个内置的本地 WebServer,根目录映射到 './public' 目录,默认端口:3000
npm start运行 Jest 测试
npm test打包应用(准备上线)
npm run build
项目结构
查看项目的react版本
npm info react
生命周期
componentDidMount() 方法会在组件已经被渲染到 DOM 中后运行
构造函数是唯一可以给this.state赋值的地方
sate的更新可能是异步的,出于性能考虑,react会把多个setState合并成一个调用,所以不能依赖他们的值来更新下一个状态
需要解决这个问题,可以让setState接受一个函数而不是对象
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
//或者
this.setState(function(state, props) {
return {
counter: state.counter + props.increment
};
});
state 为局部的或是封装的的原因。除了拥有并设置了它的组件,其他组件都无法访问。但是可以作为props向下传递
事件处理
function Form() {
function handleSubmit(e) {
e.preventDefault();
console.log('You clicked submit.');
}
return (
);
}
在这里,e 是一个合成事件。React 根据 W3C 规范来定义这些合成事件,所以你不需要担心跨浏览器的兼容性问题。React 事件与原生事件不完全相同。
1.bind指定this
class Toggle extends React.Component { constructor(props) { super(props); this.state = {isToggleOn: true}; // 为了在回调中使用 `this`,这个绑定是必不可少的 this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn })); } render() { return ( ); } } ReactDOM.render(, document.getElementById('root') );
jsx回调函数的this默认不会绑定this,函数不手动绑定this会指向undefined
2.箭头函数
class LoggingButton extends React.Component { handleClick() { console.log('this is:', this); } render() { // 此语法确保 `handleClick` 内的 `this` 已被绑定。 return ( ); } }
此语法问题在于每次渲染 LoggingButton 时都会创建不同的回调函数。在大多数情况下,这没什么问题,但如果该回调函数作为 prop 传入子组件时,这些组件可能会进行额外的重新渲染。我们通常建议在构造器中绑定或使用 class fields 语法来避免这类性能问题
3.组件
组件类必须继承 **React.Component**
- 组件类必须有 **render** 方法
组件通信
react是单向数据流,react中数据时从上自下传递的,也就是一个父组件可以把它的state/props 通过props传递给子组件,但是子组件不能修改props。如果需要修改父组件的数据,需要通过回调函数。
父组件=》子组件
数据添加子组件属性,子组件从props属性中获取
export class 父组件 extends React.Component{ constructor(props){ super(props); this.state={ text:'文本' } } render(){ return (子组件=〉父组件 在父组件中定义相关数据操作方法或者回调函数,方法传递给子组件,在子组件中调用该方法) } } export class 子组件 extends React.Component{ constructor(props){ super(props); } render(){ return ("{this.state.text}"> ) } }{this.props.text}
export class 父组件 extends React.Component{
constructor(props){
super(props);
this.state={
text:'文本'
}
}
//用的箭头函数 所以不需要bind this
changesText=()=>{
this.setState({
text:"修改了文本"
})
}
render(){
return (
<子组件 changesText={this.changesText}>修改内容子组件>
)
}
}
export class 子组件 extends React.Component{
constructor(props){
super(props);
this.state={
text:'文本'
}
}
render(){
return (
)
}
}
跨组件通信-context
React.createContext(defaultValue);
Context.Provider 在父组件调用Provider传递数据
value要传递的数据
接受数据:
-class.contextType=Context;
-static contextType =Context
-Context.Consumer
**注意在使用不熟练时,最好不要再项目中使用 context,context一般给第三方库使用**
1.
import React,{createContext} from 'react'
//新建一个context对象
const MyContext=createContext();
const {Provider} =MyContext;
class Div extends React.Component{
constructor(props){
super(props);
this.state={
text:'文本'
}
}
render(){
return (
)
}
}
class P extends React.Component{
render(){
return (
)
}
}
class Span extends React.Component{
render(){
console.log(this)//this上面就有了text
return (
{this.context}
)
}
}
//接受数据
Span.contextType=MyContext;
2.consumer 接受数据的
import React,{createContext} from 'react'
//新建一个context对象
const MyContext=createContext();
const {Provider,Consumer} =MyContext;
class Div extends React.Component{
constructor(props){
super(props);
this.state={
text:'文本'
}
}
render(){
return (
)
}
}
class P extends React.Component{
render(){
return (
{(props)=>{//Consumer接受函数,然后通过props方式传递
return ()
}}
)
}
}
class Span extends React.Component{
render(){
console.log(this)//this上面就有了text
return (
{this.props.text}
)
}
}
**XSS**
为了有效的防止 XSS 注入攻击,React DOM 会在渲染的时候把内容(字符串)进行转义,所以字符串形式的标签是不会作为 HTML 标签进行处理的
key的作用