(三)react基础知识

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、状态提升

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349