react快速入门

(三)react基础知识

2019-03-27  本文已影响0人  冬天73051

1、项目基本搭建

create-react-app是react中最简单的创建单页面程序的方式。在使用它之前先保证你的机器上安装了Node环境

# 全局安装create-react-app
$ yarn global add create-react-app
# 创建项目
create-react-app react01
cd react01
yarn start
//浏览器localhost:3000/可以查看到开启的服务

2、JSX语法简介

简单的JSX语法
const element = <h1>Hello, world!</h1>;

它被称为 JSX, 一种 JavaScript 的语法扩展


在 JSX 中使用表达式

你可以任意地在 JSX 当中使用JavaScript 表达式在 JSX 当中的表达式要包含在大括号里

const str = "hello world" + "你好世界";
const element = (
  <h1>
    Hello, {str}
  </h1>
);

JSX 本身其实也是一种表达式
在编译之后呢,JSX 其实会被转化为普通的 JavaScript 对象。
这也就意味着,你其实可以在 if 或者 for 语句里使用 JSX,将它赋值给变量,当作参数传入,作为返回值都可以

const renderJsx = () => {
  let a = 10;
  if(a > 5){
    return <div>hello {a}</div>
  }else{
    return <div>hello world</div>
  }
}

//=======调用renderJsx()即可
render(){
  return(
   <div>{renderJsx()}</div>
 )
}

JSX 属性
//你可以使用引号来定义以字符串为值的属性
const element = <div tabIndex="0"></div>;
//===
//也可以使用大括号来定义以 JavaScript 表达式为值的属性
const element = <img src={user.avatarUrl} />;

切记你使用了大括号包裹的 JavaScript 表达式时就不要再到外面套引号了。JSX 会将引号当中的内容识别为字符串而不是表达式


JSX 嵌套(可以相互嵌套)
const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);

因为 JSX 的特性更接近 JavaScript 而不是 HTML , 所以 React DOM 使用 camelCase 小驼峰命名 来定义属性的名称,而不是使用 HTML 的属性名称。

例如,class 变成了 className,而 tabindex 则对应着 tabIndex


JSX 防注入攻击

你可以放心地在 JSX 当中使用用户输入:
React DOM 在渲染之前默认会 [过滤]所有传入的值。它可以确保你的应用不会被注入攻击。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 [XSS(跨站脚本)]攻击。

const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element = <h1>{title}</h1>;

更多代码注入注意:https://zhuanlan.zhihu.com/p/28434174


3、组件&props

1、组件定义
js函数定义

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

2、你也可以使用ES6 class来定义一个组件:

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

//调用
<Welcome name="lily"/>

3、组件渲染

import React, { Component } from 'react';
import './App.css';
//====组件 Welcome
function Welcome(props) {
  return <div>hello, {props.name}</div>
}

const element = <Welcome name={"lily"}/>;

class App extends Component {
  render() {
    return (
      <div className="App">
        {element}
      </div>
    );
  }
}

export default App;

4、生命周期详解

1、state:传递及状态的改变

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

//通过事件值的改变
clickEvent(){
   this.setState({
    date: "2019-03-27"
  })
}

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

2、生命周期

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

  componentDidMount() { 
//当 `Clock` 组件第一次被渲染到 DOM 中的时候,就为其设置一个计时器这在 React 中被称为“挂载(mount)”。
//=====设置计时器:
  this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
//同时,当 DOM 中 `Clock` 组件被删除的时候,应该清除计时器这在 React 中被称为“卸载(umount)”。
    //==清除计时器
    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>
    );
  }
}

3、正确地使用 State
不要直接修改 State,此代码不会重新渲染组件

// Wrong
this.state.comment = 'Hello';

//yes
//而是应该使用 setState():
this.setState({comment: 'Hello'});

4、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
}));

5、事件处理

1、事件命名:小驼峰式(camelCase)


6、条件渲染

与运算符 &&

function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );
}

const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
  <Mailbox unreadMessages={messages} />,
  document.getElementById('root')
);

三目运算符

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
    </div>
  );
}

阻止组件渲染
在极少数情况下,你可能希望能隐藏组件,即使它已经被其他组件渲染。若要完成此操作,你可以让 render 方法直接返回 null,而不进行任何渲染

import React, { Component } from 'react';

function WarningBanner(props) {
  if (!props.warn) {
    return null;
  }

  return (
    <div className="warning">
      Warning!
    </div>
  );
}

class App extends Component {
  render() {
    return (
      <div className="App">
        <WarningBanner/>
      </div>
    );
  }
}

export default App;

在组件的 render 方法中返回 null 并不会影响组件的生命周期。例如,上面这个示例中,componentDidUpdate 依然会被调用


7、列表keys

Keys 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识
一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串
当元素没有确定 id 的时候,万不得已你可以使用元素索引 index 作为 key

const todoItems = todos.map((todo, index) =>
  // Only do this if items have no stable IDs
  <li key={index}>
    {todo.text}
  </li>
);

8、状态提升

通常,多个组件需要反映相同的变化数据,这时我们建议将共享状态提升到最近的共同父组件中去, 通过改变父级的状态统一改变子组件的状态

上一篇 下一篇

猜你喜欢

热点阅读