React相关(另外复习下数组的map、filter方法)《下》

React组件有几种特殊方法,它们提供了在组件生命周期中的特定点执行操作的机会,它们被称为生命周期方法或生命周期钩子,允许我们在特定时间点捕获组件,比如在组件被渲染之前、更新之前、接收道具之前、卸载之前等等。下面是一些主要生命周期方法:componentWillMount()、 componentDidMount()、 shouldComponentUpdate()、 componentDidUpdate()、 componentWillUnmount() ,下面将涵盖这些生命周期方法的一些基本用法(其中componentWillMount()在16.X版本中被弃用,在版本17中被删除)。

看下例,我们将组件加载入DOM时,在render()方法之前就调用componentWillMount()方法,使用componentWillMount()在控制台中记录一些内容:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  componentWillMount() {
    console.log('hahaha');
  }
  render() {
    return <div />
  }
};
//将组件渲染到DOM:
ReactDOM.render(<MyComponent/>,document.getElementById('challenge-node'));
/*控制台输出:
hahaha
*/

使用React时,我们有时需要调用API终点来检索数据,了解在何处执行此操作非常重要。最好是在生命周期方法componentDidMount()中对服务器进行API调用或任何调用,组件加载到DOM后就会调用此方法。对setState()的任何调用都将触发组件的重新渲染,当我们在此方法中调用API并使用API返回的数据设置state时,一收到数据组件就会自动触发更新。

下面例子中,componentDidMount()中有一个模拟API调用,它在2.5秒后设置state,以模拟调用服务器检索数据。此示例请求站点的当前活动用户总数。在render方法中,h1元素里,文本“Active Users:”之后呈现activeUsers的值:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      activeUsers: null
    };
  }
  componentDidMount() {
    setTimeout(() => {
      this.setState({
        activeUsers: 1273
      });
    }, 2500);
  }
  render() {
    return (
      <div>
        <h1>Active Users:{this.state.activeUsers} </h1>       
      </div>
    );
  }
}
//将组件渲染到DOM:
ReactDOM.render(<MyComponent/>,document.getElementById('challenge-node'));

/*刚开始DOM输出:
Active Users:
2.5秒后DOM输出:
Active Users:1273
*/

如何添加事件侦听器?componentDidMount()方法是添加事件侦听器的最佳位置。React提供了一个综合事件系统,它包装了浏览器中的本机事件系统。这意味着,无论用户的浏览器如何,综合事件系统的行为都完全相同,即使本地事件在不同浏览器之间的行为可能不同。我们已经使用了一些综合事件处理程序,如onClick()。React的综合事件系统非常适合您在DOM元素上管理的大多数交互。但是,如果要将事件处理程序附加到文档或窗口对象,则必须直接执行此操作。

看个例子:在componentDidMount()方法中为“keydown”事件贴上一个事件监听器,并让这些事件触发函数handleKeyPress()。然后在componentWillUnmount()方法中删除同一个事件侦听器,在卸载和销毁React组件之前,最好使用此生命周期方法对其进行清理,所谓"移除事件侦听器"就是这样一个清理操作。【这里使用了“document.addEventListener()”,它将事件(用引号括起来)作为第一个参数,将回调函数作为第二个参数。】

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: ''
    };
    this.handleEnter = this.handleEnter.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
  }
  //利用document.addEventListener(),keydown事件会触发handleKeyPress方法执行。
  componentDidMount() {
    document.addEventListener('keydown',this.handleKeyPress);
  }
  componentWillUnmount() {
    document.removeEventListener('keydown',this.handleKeyPress);
  }
  handleEnter() {
    this.setState((state) => ({
      message: state.message + 'You pressed the enter key! '
    }));
  }
  handleKeyPress(event) {
    //只有按下enter键才会调用handleEnter方法
    if (event.keyCode === 13) {
      this.handleEnter();
    }
  }
  render() {
    return (
      <div>
        <h1>{this.state.message}</h1>
      </div>
    );
  }
};
//将组件渲染到DOM:
ReactDOM.render(<MyComponent/>,document.getElementById('challenge-node'));
/*当按下回车键,页面会出现"You pressed the enter key!",多次按下则呈现一长串的"You pressed the enter key!"。*/

任何组件接收到新的state或新的props,它将重新渲染自己及其所有子组件。但React提供了一个生命周期方法,当子组件接收到新的state或props时,可以调用它,明确声明组件是否应该更新。该方法是shouldComponentUpdate(),它使用nextProps和nextState作为参数。

此方法是优化性能的有效方法。例如,默认是组件在收到新的props时重新渲染,即使props没有更改。我们可以通过使用shouldComponentUpdate()比较props来防止这种情况。该方法必须返回一个布尔值,告诉React是否更新组件。我们可以将当前的props(this.props)与下一个props(nextProps)进行比较,以确定是否需要更新,并相应地返回true或false。 

看个例子:只要按钮点击次数为偶数次就渲染组件。

class OnlyEvens extends React.Component {
  constructor(props) {
    super(props);
  }
  shouldComponentUpdate(nextProps, nextState) {
    console.log('Should I update?');
    //检查nextProps的值nextProps.value是否为偶数,是则返回true否则返回false。 
    return nextProps.value%2==0?true:false;
  }
  componentDidUpdate() {
    console.log('Component re-rendered.');
  }
  render() {
    return <h1>{this.props.value}</h1>;
  }
}

class Controller extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0
    };
    this.addValue = this.addValue.bind(this);
  }
  addValue() {
    this.setState(state => ({
      value: state.value + 1
    }));
  }
  render() {
    return (
      <div>
        <button onClick={this.addValue}>Add</button>
        <OnlyEvens value={this.state.value} />
      </div>
    );
  }
}
//将组件渲染到DOM:
ReactDOM.render(<Controller/>,document.getElementById('challenge-node'));
/*
点击按钮奇数次返回:
Should I update?
点击按钮偶数次返回:
Should I update?
Component re-rendered.
*/

如何在React中创建JSX元素的样式呢?说两种情况:

一、从样式表中导入样式,这没有什么不同,使用className属性将类应用于JSX元素,并将样式应用于样式表stylesheet中的类。(JSX使用className来定义HTML类,不能再使用单词class来定义HTML类,因为class是JavaScript中的保留字)

const JSX = (
  <div className='myDiv'>
    <h1 >Add a class to this div</h1>
  </div>
);

二、应用内联样式,这在ReactJS开发中非常常见。将内联样式应用于JSX元素,类似于在HTML中的方式,但有一些JSX差异。

以下是HTML中内联样式的示例:

<div style="color: yellow; font-size: 16px">Mellow Yellow</div>

以下是React中JSX元素内联样式的示例:

<div style={{color: "yellow", fontSize: 16}}>Mellow Yellow</div>

JSX元素使用样式属性,但由于JSX的转换方式,不能将值设置为字符串,应将其设置为JavaScript对象。注意外层{ }表示这是JS语句,里层{ }表示这里面是JS对象。React不接受样式对象中的"烤肉串"式写法,故在React中,要把样式中的属性名改为“小驼峰”写法,然后React将在HTML中为我们应用正确的属性名称。看个具体例子:

class Colorful extends React.Component {
  render() {
    return (
      //fontSize:72也可以写为fontSize:'72px'。
      <div style={{color:'red',fontSize:72}}>Big Red</div>
    );
  }
};
//将组件渲染到DOM:
ReactDOM.render(<Colorful/>,document.getElementById('challenge-node'));
/*页面输出72px大小的红色字体:
Big Red
*/

像font-size这样带有连字符号的词对于JavaScript对象属性来说是无效的语法,所以在React中我们使用"小驼峰原则"对其进行改写。通常,在JSX中,任何带有连字符的style属性都是使用"小驼峰原则"编写的。

除非另有规定,否则所有属性值长度单位(如height, width, fontSize)均默认为px。若想使用em,可以将值和单位用引号括起来,如{fontSize:“4em”}。除了默认为px的长度值之外,所有其他属性值都应该用引号括起来

如果有大量样式,可以将样式对象分配给常量,以保持代码的整洁有序,然后将样式常量赋给style属性。看个例子:

//定义全局常量
const styles={color:'purple',fontSize:40,border:'2px solid purple'};
class Colorful extends React.Component {
  render() {
    return (
      //将全局变量styles赋给属性style
      <div style={styles}>Style Me!</div>
    );
  }
};
//将组件渲染到DOM:
ReactDOM.render(<Colorful/>,document.getElementById('challenge-node'));
/*页面输出带有2px实线紫色边框的40px大小的紫色字体:
Style Me!
*/

目前为止,我们已经知道如何使用花括号{ }将JavaScript代码注入JSX代码,如访问props、传递props、访问state、在代码中插入注释,以及给组件添加样式。这些都是将JavaScript放在JSX中的常见用法,但还有其他方法可以在React组件中直接使用JavaScript代码。

我们可以在render方法中,位于return语句之前直接编写JavaScript,而无需将其插入花括号中,因为它还不在JSX代码中。若稍后要在return语句中的JSX代码中使用前面编写的JavaScript变量,将变量名放在花括号内即可使用。

看个例子:render方法具有一个包含20个短语的数组,包含了1980年代经典的魔术八球玩具中找到的答案。在输入框中输入内容,点击按钮,就会随机呈现一句短语。

//定义inputStyle常量
const inputStyle = {
  width: 235,
  margin: 5
};
//定义MagicEightBall类组件
class MagicEightBall extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userInput: '',
      randomIndex: ''
    };
    //将ask、handleChange方法跟this(即类组件MagicEightBall)绑定
    this.ask = this.ask.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }
  ask() {
    if (this.state.userInput) {
      this.setState({
        //运用数学计算返回随机值给randomIndex,用作数组下标
        randomIndex: Math.floor(Math.random() * 20),
        //同时清空输入框
        userInput: ''
      });
    }
  }
  handleChange(event) {
    this.setState({
      //获取输入框的值赋给userInput
      userInput: event.target.value
    });
  }
  render() {
    const possibleAnswers = [
      'It is certain',
      'It is decidedly so',
      'Without a doubt',
      'Yes, definitely',
      'You may rely on it',
      'As I see it, yes',
      'Outlook good',
      'Yes',
      'Signs point to yes',
      'Reply hazy try again',
      'Ask again later',
      'Better not tell you now',
      'Cannot predict now',
      'Concentrate and ask again',
      "Don't count on it",
      'My reply is no',
      'My sources say no',
      'Most likely',
      'Outlook not so good',
      'Very doubtful'
    ];
    //定义常量answer,将上面产生的随机值用作数组下标,然后取值赋给常量answer
    const answer=possibleAnswers[this.state.randomIndex]; 
    return (
      <div>
        <input
          type='text'
          /*将userInput赋给value属性*/
          value={this.state.userInput}
          /*将handleChange方法赋给onChange事件*/
          onChange={this.handleChange}
          /*将inputStyle常量赋给style属性*/
          style={inputStyle}
        />
        <br />
        {/*将ask()赋值给按钮的onClick事件*/}
        <button onClick={this.ask}>Ask the Magic Eight Ball!</button>
        <br />
        <h3>Answer:</h3>
        <p>
          {/*使用常量answer*/}
          {answer}
        </p>
      </div>
    );
  }
}
//将类组件渲染到DOM:
ReactDOM.render(<MagicEightBall/>,document.getElementById('challenge-node'));
View Code

使用JavaScript控制渲染视图(呈现的节点)的另一个应用是将渲染的元素绑定到条件。当条件为true时渲染一个视图,当它是false时呈现另一个画面。通过在React组件的render()方法中使用if/else语句可以实现这一点。看个例子:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      display: true
    }
    this.toggleDisplay = this.toggleDisplay.bind(this);
  }
  toggleDisplay() {
    this.setState((state) => ({
      //点击按钮时会执行此代码,每点一次就将display设置为上一次的值取反
      display: !state.display
    }));
  }
  render() {
    //编写JS代码,使用if/else判断return哪个JSX
    if(this.state.display) {
      return (
       <div>
         <button onClick={this.toggleDisplay}>Toggle Display</button>
         <h1>Displayed!</h1>
       </div>
    );
    }
    else {
      return (
       <div>
       {/*将toggleDisplay方法赋给按钮的onClick事件*/}
         <button onClick={this.toggleDisplay}>Toggle Display</button>
       </div>
    );
    }
  }
};
//将组件渲染到DOM:
ReactDOM.render(<MyComponent/>,document.getElementById('challenge-node'));
/*
每一次点击按钮,呈现的画面都与上一次不同,画面在“按钮”和“按钮+Displayed!”之间来回切换。
*/

假设要跟踪组件中的几个条件,并且希望根据每个条件渲染不同的元素。这时编写大量的else If语句来返回稍有不同的UI会有很多重复代码,从而留下出错的空间。我们可以使用&&逻辑运算符以更简洁的方式执行条件逻辑。如果条件为true则返回一些标签,条件为false则在评估条件后立即返回false,而不返回任何内容。您可以将这种语句直接包含在JSX中,并通过在每个语句后面写&&将多个条件串在一起。如此我们就能在render()方法中处理更复杂的条件逻辑,而无需重复大量代码。语法如下:

{condition && <p>markup</p>}

上面的例子改写一下,能通过&&这种方法实现一样的功能:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      display: true
    }
    this.toggleDisplay = this.toggleDisplay.bind(this);
  }
  toggleDisplay() {
    this.setState(state => ({
      display: !state.display
    }));
  }
  render() {
    /*return (
       <div>
         <button onClick={this.toggleDisplay}>Toggle Display</button>
         <h1>Displayed!</h1>
       </div>
    );*/
    return (
       <div>
         <button onClick={this.toggleDisplay}>Toggle Display</button>
         {/*如果条件为真,则返回一些标签*/}
         {this.state.display===true &&<h1>Displayed!</h1>}
       </div>
    );
  }
};

要通过JavaScript条件来呈现所需内容,还有一种方法:三元运算符。三元运算符通常用作JavaScript中if/else语句的快捷方式。由于JSX的编译方式,if/else语句不能直接插入JSX代码中,当需要if/else语句时,它总是写在return语句之外。如果我们想在JSX中实现条件逻辑,三元表达式就成了一个很好的选择。我们还可以将几个三元表达式组合在一起。

基本语法:condition ? expressionIfTrue : expressionIfFalse;

看个例子:

const inputStyle = {
  width: 235,
  margin: 5
};

class CheckUserAge extends React.Component {
  constructor(props) {
    super(props);
    //注意state的初始化语法很容易写错!(=装有键值对的对象)
    this.state={
      input:'',
      userAge:''
    }
    this.submit = this.submit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(e) {
    this.setState({
      input: e.target.value,
      userAge: ''
    });
  }
  submit() {
    this.setState(state => ({
      userAge: state.input
    }));
  }
  render() {
    const buttonOne = <button onClick={this.submit}>Submit</button>;
    const buttonTwo = <button>You May Enter</button>;
    const buttonThree = <button>You Shall Not Pass</button>;
    return (
      <div>
        <h3>Enter Your Age to Continue</h3>
        <input
          style={inputStyle}
          type='number'
          value={this.state.input}
          onChange={this.handleChange}
        />
        <br />
        {/*当页面首次加载时,将提交按钮buttonOne呈现到页面。然后,当用户输入年龄并单击按钮时,根据年龄呈现不同的按钮。如果数字小于18,
则呈现buttonThree。如果数字大于或等于18,则呈现buttonTwo。
*/} {this.state.userAge=='' ? buttonOne: (this.state.userAge>=18 ? buttonTwo:buttonThree) } {/*在JSX中使用三目运算符要用花括号括起来,以识别为JS代码。至于那些在return前就写好的JS代码,其中的变量名在这里直接用就好了,
不用拿花括号括起来。另外,上面的小括号去掉也行。
*/} </div> ); } } //将组件渲染到DOM: ReactDOM.render(<CheckUserAge/>,document.getElementById('challenge-node'));

 如何将if/else、&&和三元运算符中的任何一个或全部与另一个强大的React特性props结合起来呢?即用prop的值来自动决定要呈现什么。下面我们让一个子组件Results根据其props做出渲染决策:

class Results extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    {/*通过三元表达式,依据条件的真假返回不同的语句*/}
    return <h1>{this.props.fiftyFifty>=.5 ? 'You Win!': 'You Lose!'}</h1>;
  }
}

class GameOfChance extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 1
    };
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    this.setState(prevState => {
      //形参prevState代表this.state里的所有键值对
      return {
        //记录总共玩了多少次
        counter: prevState.counter+1
      }
    });
  }
  render() {
    /*JS代码:定义一个常量expression,Math.random()方法每次调用时都返回一个介于0(包含)和1(不包含)之间的值。因此,对于50/50赔率,
在表达式中使用Math.random()>=.5。从统计学上讲,这个表达式将在50%的时间内返回true,而在其他50%的时间里返回false。
*/ const expression =Math.random()>=.5; return ( <div> {/*用户按下按钮查看是输还是赢*/} <button onClick={this.handleClick}>Play Again</button> {/*给Results的props传递一个名为fiftyFifty的prop,并将常量expression赋给这个fiftyFifty*/} <Results fiftyFifty={expression} /> {/*用户玩了的次数*/} <p>{'Turn: ' + this.state.counter}</p> </div> ); } } //将父组件渲染到DOM: ReactDOM.render(<GameOfChance/>,document.getElementById('challenge-node'));

如何根据React组件的state有条件地呈现CSS?要做到这一点,我们需要检查一个条件,如果满足该条件,需要在render方法中修改分配给JSX元素的样式对象。理解这个范式很重要,因为它与直接修改DOM元素(这在jQuery中非常常见)的更传统的应用样式的方法有很大的不同。在那种方法中,必须跟踪元素何时更改,并直接处理实际操作。跟踪更改可能会变得困难,可能会使UI变得不可预测。而当我们根据条件设置样式对象时,我们将UI的外观作为应用程序state的一个函数。这样就有了一个只在一个方向上移动的清晰的信息流,这是使用React编写应用程序时的首选方法。

看个例子:要求如果用户输入超过15个字符就改变输入框的样式。

class GateKeeper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({ input: event.target.value })
  }
  render() {
    //使用JS定义inputStyle变量,后续赋给输入框的style属性(CSS)
    let inputStyle = {
      border: '1px solid black'
    };
    //满足条件就更改inputStyle变量的值
    if(this.state.input.length>15){
      inputStyle = {
      border: '3px solid red'
      };
    };
    return (
      <div>
        <h3>Don't Type Too Much:</h3>
        <input
          type="text"
          style={inputStyle}
          value={this.state.input}
          onChange={this.handleChange} />
      </div>
    );
  }
};
//将GateKeeper渲染到DOM:
ReactDOM.render(<GateKeeper/>,document.getElementById('challenge-node')); 

如何根据用户的输入动态渲染未知数量的元素呢?通常在反应式编程中,程序员在程序运行之前无法知道应用程序的state,因为这很大程度上取决于用户与该程序的交互。程序员需要编写代码来提前正确处理未知state。例如,页面有个textarea供用户输入待办清单,我们无法知道用户会输入多少内容,需要设置组件以动态呈现正确数量的列表元素:

//JS语句,定义常量textAreaStyles方便后面赋给textarea元素的style属性
const textAreaStyles = {
  width: 235,
  margin: 5
};

class MyToDoList extends React.Component {
  constructor(props) {
    super(props);
    //初始化state
    this.state={
      userInput:'',
      toDoList:[]
    }
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }
  handleSubmit() {
    const itemsArray = this.state.userInput.split(',');
    this.setState({
      toDoList: itemsArray
    });
  }
  handleChange(e) {
    this.setState({
      userInput: e.target.value
    });
  }
  render() {
    //JS语句,将用户输入的内容转变成数组toDoList之后,使用map将每一个数组元素变成li标签的内容
    const items = this.state.toDoList.map(i=>{return <li>{i}</li>});
    return (
      <div>
        <textarea
          onChange={this.handleChange}
          value={this.state.userInput}
          style={textAreaStyles}
          placeholder='Separate Items With Commas'
        />
        <br />
        <button onClick={this.handleSubmit}>Create List</button>
        <h1>My "To Do" List:</h1>
        {/*使用上面定义的JS常量items的值*/}
        <ul>{items}</ul>
      </div>
    );
  }
}
//将MyToDoList渲染到DOM:
ReactDOM.render(<MyToDoList/>,document.getElementById('challenge-node')); 

上面的例子缺少了一个重要的部分。当创建元素数组时,每个元素都要有一个设置为唯一值的key属性。React使用这些键来跟踪添加、更改或删除了哪些项。当元素列表有所修改时,这就能使重新渲染过程更加高效。注意:key只需要在同级元素之间唯一,它们在应用程序中不需要全局唯一。 

看个例子:

//JS语句,定义常量frontEndFrameworks
const frontEndFrameworks = [
  'React',
  'Angular',
  'Ember',
  'Knockout',
  'Backbone',
  'Vue'
];
//定义无状态函数组件Frameworks
function Frameworks() {
  //JS语句,使用数组索引作为键(应避免):
  //const renderFrameworks = frontEndFrameworks.map((item,index)=>{return <li key={index}>{item}</li>}); 
  //JS语句,使用数组元素作为键:
  const renderFrameworks = frontEndFrameworks.map((i)=>{return <li key={i}>{i}</li>}); 

  return (
    <div>
      <h1>Popular Front End JavaScript Frameworks</h1>
      <ul>
      {/*使用上面定义的常量renderFrameworks,将数组元素以li的形式罗列在页面上*/}
        {renderFrameworks}
      </ul>
    </div>
  );
};
//将无状态函数组件Frameworks渲染到DOM:
ReactDOM.render(<Frameworks/>,document.getElementById('challenge-node')); 

filter根据条件过滤数组的内容,然后返回一个新数组。例如,有一个users用户数组,所有用户都有一个可以设置为true或false的online属性,则可以通过编写以下内容来筛选出那些online为true的用户:

let onlineUsers = users.filter(user => user.online);

看个例子:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      users: [
        {
          username: 'Jeff',
          online: true
        },
        {
          username: 'Alan',
          online: false
        },
        {
          username: 'Mary',
          online: true
        },
        {
          username: 'Jim',
          online: false
        },
        {
          username: 'Sara',
          online: true
        },
        {
          username: 'Laura',
          online: true
        }
      ]
    };
  }
  render() {
    //筛选出online为true的数组元素,返回新数组
    const usersOnline = this.state.users.filter(i=>i['online']); 
    //将新数组的每个元素的username属性放到li里,后续在页面呈现出来   //别忘了给每个元素数组一个key属性
    const renderOnline =usersOnline.map((item)=>{return <li key={item.username}>{item['username']}</li>}) ; 

    return (
      <div>
        <h1>Current Online Users:</h1>
        <ul>{renderOnline}</ul>
      </div>
    );
  }
}
//将类组件MyComponent渲染到DOM:
ReactDOM.render(<MyComponent/>,document.getElementById('challenge-node')); 

以上一直是在客户端上渲染React组件,那么如何在服务器上呈现React组件呢?既然React是一个JavaScript视图库,那么通过Node(节点、对象)在服务器上运行JavaScript应该是可以的。React提供了一个renderToString()方法,通过它我们可以在服务器上呈现React组件。为什么应用程序中的组件要在服务器上渲染呢?首先,如果不这样做,当我们的React应用程序最初加载到浏览器时,将是由一个相对来说是空的HTML文件和一大堆JavaScript组成的。这对于搜索引擎来说并不理想,因为搜索引擎试图为我们的页面内容编制索引,以便人们能够找到它。而当我们在服务器上呈现初始的HTML标记并将其发送给客户端时,初始页面加载就会包含搜索引擎可以爬网的所有页面标记。其次,这样可以创建更快的初始页面加载体验,因为渲染的HTML比整个应用程序的JavaScript代码体量要小。React仍能识别我们的应用程序并在首次加载后进行管理。看个例子:

class App extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <div/>
  }
};
//将组件App渲染到服务器:
/*renderToString()方法是ReactDOMServer(在这里提供为全局对象)提供的。该方法接受一个参数,参数是React元素*/
ReactDOMServer.renderToString(<App/>);

。。。

posted @ 2022-10-21 15:44  枭二熊  阅读(531)  评论(0编辑  收藏  举报