react.js avoid re rendering the entire page when typing (setState) in input/textareah

Posted by smurl on Fri, 08 Nov 2019 20:56:47 +0100

Background:
Using setState to save value in the onChange method of < textarea > will result in input stuttering. The reason is that the user is always in setState when inputting, resulting in the whole page being re rendered all the time

Main page:

import React, {
  Component,
} from 'react';
import { Input } from 'antd';

const { TextArea } = Input;

class CustomCompent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      targetValue: '',
    };
  }

   handleChange = e => {
      let targetValue = e.target.value;
      this.setState({
        targetValue,
      });
    };

    render() {
      const { targetValue } = this.state;

      return (
        <>
          xxxx
          xxxx
          <TextArea
            onChange={this.handleChange}
            value={targetValue}
          />
          <p>{targetValue.length}/100</p>
        </>
      );}

resolvent:
Encapsulate the < textarea > component as a single component, so that it will only trigger its own re rendering instead of the entire page!

TextArea component:

import React from 'react';
import { Input } from 'antd';

const { TextArea } = Input;

class CountTextArea extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      targetValue: '',
    };
  }

  handleChange = value => {
    let targetValue = value.target.value;
    this.setState({
      targetValue,
    });
  };

  render() {
    const {  setRef } = this.props;
    const { targetValue } = this.state;

    return (
      <>
        <TextArea
          onChange={this.handleChange}
          value={targetValue}
          ref={setRef}
        />
        <p>{targetValue.length}/100</p>
      </>
    );
  }
}

export default CountTextArea;

Main page:

import React, {
  Component,
} from 'react';
import { Button } from 'antd';
import CountTextArea from './CountTextArea';

class CustomCompent extends Component {
  componentDidMount() {
    this.customTextArea = React.createRef();
  }

  handleOk = () => {
    if (this.customTextArea && this.customTextArea.current) {
      //send content
      let value =this.customTextArea.current.textAreaRef.value
      //xxx
    }
  }

  render() {

    return (
      <>
        <CountTextArea
          handleOk={this.handleOk}
          setRef={this.customTextArea}
        />
        <Button onClick={this.handleOk}>Send out</Button>
      </>
    );
  }
}

In this way, users can input the value of setState textarea happily~

(end)

Topics: Javascript React