React 学习总结

文章目录

  • 一、React安装
    • 静态文件方式
    • npm方式安装
  • 二、JSX
    • 1. JSX 是什么
    • 2. JSX 优点
    • 3. JSX 语法
      • 1. 如果输出多行结构,可以使用一对小括号来包含整个结构
      • 2. 在 JSX 中可以嵌套表达式
      • 3. JSX 中的注释
      • 4. JSX 更偏向于 JavaScript,所以对于一些特殊的属性,使用的是 JavaScript 中的属性名风格
      • 5. 为了更加方便的操作元素的style,针对style这个属性有特殊的处理
      • 6. JSX 中的表达式也可以使用在属性上,但是使用的时候需要注意;不要使用引号包含
  • 三、React创建组件的方式和区别
    • 1. 无状态函数式组件
    • ~~2. React.createClass~~
    • 3. React.Component
      • 补充一点
      • 总结:
  • 四、组件&props
  • 五、state&生命周期
    • 1. state
    • 2. 生命周期
  • 六、事件处理
  • 七、条件渲染
  • 八、列表&key
  • 九、表单
    • 1. 受控组件
  • 十、状态提升
  • 十一、组合 vs 继承
    • 1. 组合
  • 十二、不可变性


提示:以下是本篇文章正文内容,下面案例可供参考

一、React安装

静态文件方式

你可以直接使用静态文件CDN的React CDN 库,地址如下

<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>

也可以使用官方提供的 CDN地址:

<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>

第一个实例:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8" />
	<title>Hello React!</title>
  <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>
</head>
<body>
  <div id="example"></div>
  
  <script type="text/babel">
    ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('example')
    );
  </script>
 
</body>
</html>

npm方式安装

搭建本地环境

npx create-react-app my-app

参考链接: https://react.docschina.org/tutorial/tutorial.html#setup-option-2-local-development-environment

二、JSX

JSX 在 React 中是可选的,开发人员也经常使用这种语法

1. JSX 是什么

JSX 是一个基于 JavaScript + XML 的一个扩展语法。它可以作为值使用;但并不是字符串,也不是HTML;它可以配合JavaScript表达式一起使用

2. JSX 优点

  • JSX执行更快,因为它在编译为JavaScript代码后进行了优化
  • 它是类型安全的,在编译过程中就能发现错误
  • 使用JSX编写模块更加简单快速

3. JSX 语法

1. 如果输出多行结构,可以使用一对小括号来包含整个结构

const App = (
	<div>
  	<h1>前端学习</h1>
  </div>
)

⚠ 注意:JSX 只能有一个顶级父元素

2. 在 JSX 中可以嵌套表达式

let name = '前端';
const App = (
	<div>
  	<h1>{ name }</h1>
  </div>
)

if/for/while这些都是语句,JSX不支持语句

<h1>{ if(true) {...} }</h1>

3. JSX 中的注释

<div>
  { /* 注释 */}
</div>

4. JSX 更偏向于 JavaScript,所以对于一些特殊的属性,使用的是 JavaScript 中的属性名风格

const App = (
	<div class="box1"></div>
)const App = (
	<div className="box1"></div>
)

5. 为了更加方便的操作元素的style,针对style这个属性有特殊的处理

const App = (
	<div style={{ width:'100px' }}>
  </div>
)
// 这里的两个 '{{ }}',外部的大括号表示的是前面说的表达式语法中的大括号,
// 里面的大括号是表示对象的大括号
let skin = { width: '100px' }

6. JSX 中的表达式也可以使用在属性上,但是使用的时候需要注意;不要使用引号包含

let id = '0001';
const App = (<div id="{id}"></div>);const App = (<div id={id}></div>);

三、React创建组件的方式和区别

前提:html文件引入了react 库 或者 搭建了本地环境

1. 无状态函数式组件

function HelloComponent(props) {
  return <h1>Hello { props.name }</h1> 
  或者
  return(
  	<h1>Hello { props.name }</h1>
  )
}
ReactDOM.render(
	<HelloComponent />,
    document.getElementById('root')
)

无状态的创建形式使代码的可读性更好,并且减少了大量冗余的代码,精简只有一个render方法,大大的增强了编写一个组件的便利,除此之外无状态组件还有以下几个显著的特点:
① 组件不会被实例化,整体渲染性能得到提升
因为组件被精简成一个render方法的函数来实现的,由于是无状态组件,所以无状态组件就不会再有组件实例化的过程,无实例化过程也就不需要分配多余的内存,从而性能得到一定的提升。

② 组件不能访问 this对象
无状态组件由于没有实例化过程,所以无法访问组件this中的对象,例如:this.refthis.state等均不能访问。若想访问就不能使用这种形式来创建组件。

③ 组件无法访问生命周期的方法
因为无状态组件是不需要组件生命周期管理和状态管理,所以底层实现这种形式的组件时是不会 实现组件的生命周期方法。所以无状态组件是不能参与组件的各个生命周期管理的。

④ 无状态组件只能访问输入的props,同样的props会得到同样的渲染结果,不会有副作用
无状态组件被鼓励在大型项目中尽可能以简单的写法来分割原本庞大的组件,未来React也会这种面向无状态组件在譬如无意义的检查和内存分配领域进行一系列优化,所以,只要有可能,尽量使用无状态组件

2. React.createClass

这种方式已经被淘汰,所以不做过多介绍。

3. React.Component

class App extends React.Component {
		constructor(props) {
    		super(props);
      	    this.state = {
        	  value: 0
            }
    }
  	render() {
    	return(
      	  <div></div>
       )
    }
}
ReactDOM.render(
	<App />,
    document.getElementById('root')
)

补充一点

无状态组件内部其实是可以使用 ref 功能的,虽然不能通过通过 this.refs 访问到,但是可以通过将 ref 内容保存到无状态组件内部的一个本地变量中获取到

例如下面这段代码可以使用ref来获取组件挂载到dom中后所指向的dom元素

function HelloComponent(props) {
	let ref;
  return(
  	<div>
    	<div ref={ (node) => ref=node }>
      	...
      </div>
    </div>
  )
}

总结:

不需要使用状态 state 和 访问 this 对象的时候建议使用无状态函数式组件定义;
如果含有状态,需要访问this对象,则推荐使用 React.Component

四、组件&props

组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。

// 函数组件
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
// class 组件
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

五、state&生命周期

1. state

一般使用到 state,我们应该用 class 组件

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

总结

  1. 不要直接修改state,通过 this.setState 修改
  2. this.setState({}) 构造函数是唯一可以给 this.state 赋值的地方
  3. 异步时,this.setState 接收一个函数而非一个对象
  4. state 除了拥有并设置了它的组件,其它组件无法访问
  5. state 使用的情况:用户输入的搜索词、复选框是否选中的值
// 2. 异步解释
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
或者
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});

2. 生命周期

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
//componentDidMount()方法会在组件已经被渲染到 DOM 中后运行
  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
//componentDidMount()方法会在组件从 DOM 中移除时运行
  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

六、事件处理

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

总结

  • 事件属性命名使用小驼峰,JSX传入一个函数,而非字符串
  • 不能通过 false 方式阻止默认行为,可通过显式 preventDefault
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 为了在回调中使用 `this`,这个绑定是必不可少的
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);

总结
为了在回调中使用 this
方式① :在 constructor 中改变 this 指向

this.handleClick = this.handleClick.bind(this)

方式②:使用箭头函数

<button onClick={ () => this.handleClick }></button>

向事件处理程序传递参数

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

上述两种方式是等价的,分别通过箭头函数Function.prototype.bind 来实现。
在这两种情况下,React 的事件对象 e 会被作为第二个参数传递。如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。


七、条件渲染

可参考官方文档:https://react.docschina.org/docs/conditional-rendering.html

八、列表&key

可参考官方文档:https://react.docschina.org/docs/lists-and-keys.html

九、表单

1. 受控组件

在 HTML 中,表单元素(如、 和 )之类的表单元素通常自己维护 state,并根据用户输入进行更新。而在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState() 来更新。
我们可以把两者结合起来,使 React 的 state 成为“唯一数据源”。渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('提交的名字: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          名字:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="提交" />
      </form>
    );
  }
}

总结

  • 受控组件的事件处理函数程序接收 event 对象,可通过 event.target.value 获取受控组件的值
  • 在受控组件上指定 value 的 prop 会阻止用户更改输入。如果你指定了 value,但输入仍可编辑,则可能是你意外地将value 设置为 undefined 或 null

十、状态提升

可参考官方文档:https://react.docschina.org/docs/lifting-state-up.html

十一、组合 vs 继承

1. 组合

  • props.children
    这使得别的组件可以通过 JSX 嵌套,将任意组件作为子组件传递给它们
function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}

function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}

少数情况下,你可能需要在一个组件中预留出几个“洞”。这种情况下,我们可以不使用 children,而是自行约定:将所需内容传入 props,并使用相应的 prop。

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}
  • 特例关系
    在 React 中,我们也可以通过组合来实现这一点。“特殊”组件可以通过 props 定制并渲染“一般”组件:
function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
    </FancyBorder>
  );
}

function WelcomeDialog() {
  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!" />
  );
}

十二、不可变性

时间旅行,即保存历史记录
可参考官方文档:https://react.docschina.org/tutorial/tutorial.html#adding-time-travel

你可能感兴趣的:(React,javascript,react.js,前端)