React Advanced selection of the appropriate component type

This article is reproduced in: Ape 2048 website ➪ React Advanced select the appropriate components of the type

Recent projects basically with React, today summarizes several forms React Component share a common, often do not know how to split the code, this article may be helpful to you if you write React.

Original link: https://w3ctrain.com/2018/11/05/react-component-types/

For a fuller understanding React, to get to know what is usually written JSX Yes. Beginner confused when there are relatively large, this is a new language? Most people are hastily swept the document has been developing. By babel-presets-react treatment can be seen, in fact, JSX just syntactic sugar, eventually running in the browser or JS. React Component eventually created by React.createElement. In short, in fact, write React to write JS .

JSX

SFC (Stateless Functional Component)

React Function can be used to create a Component, Component does not have this kind of lifecycle, the interior does not maintain state, as long as the incoming props have changed is re-rendered.

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

Written by an arrow function is also more concise.

const Welcome = props => <h1>Hello, {props.name}</h1>;

The above two forms es5 generated code is the same.

var Welcome = function Welcome(props) {
  return _react2.default.createElement(
    "h1",
    null,
    "Hello, ",
    props.name
  );
};

SFC is characterized by pure only render, no other code is short conditional branch, and compared to the amount of code compiler class Component will be less.

Embarrassing is that, in 16.7 React REACT Hooks came out, SFC name is ambiguous, because to spend useState, SFC may also have local state, can also have a lifecycle. Then called Stateless Components very embarrassed, changed his name to FC?

HOC (Higher-Order Components)

For higher-order components Vue developers should be a foreign concept (do not know, when I used the Vue have not seen similar usage). From the code point of view, it is a high-order component method, passing in a component returns another component.

function logProps(WrappedComponent) {
  return class extends React.Component {
    componentWillReceiveProps(nextProps) {
      console.log('Current props: ', this.props);
      console.log('Next props: ', nextProps);
    }
    render() {
      return <WrappedComponent {...this.props} />;
    }
  }
}

The most common high-end components are react-redux inside the connect method, by passing the component and map * ToProps way for assembly and store connection. Value after internal components can connect directly obtained by the props.

exprot default connect(
  mapStateToProps,
  mapDispatchToProps,
)(Component);

Higher-order components suitable for extensions, this part of the function pulled out from the business component, the need to put, to remove when not needed, to be wrapped very small invasive component.

Dynamic Component

In some business scenarios, it can only be determined in the implementation of any specific label or component Yes. React world in which, beginning with a capital letter will be treated as a dynamic component loads, and begins with a lowercase letter it will be considered HTML DOM tag.

// Heading.js
render() {
    const { tag: Tag, children } = this.props;
    return <Tag>{ children }</Tag>
}

All is based on JS theory, as long as the incoming different tag label, it will render a different heading tags.

heading

We used this way, the components and configuration data at a rear end, after rendering the content corresponding to the front end read the configuration.

FaCC(Functions as Child Components)

React children can also be a Function type, if a direct call it what way? Loading a component such as the package, children will provide loading parameters, and then need to render the business component in accordance with what is determined loading.

class LoadArea extends Component {
  state = {
    loading: true,
  };

  componentDidMount() {
    asyncFunc()
        .then(() => {
            this.setState({
              loading: false,
            })
        })
        .catch(() => {
            this.setState({
              loading: false,
            })
        })
  }

  render() {
    return (
      <React.Fragment>
        {this.props.children({
          ...this.props,
          ...this.state,
        })}
      </React.Fragment>
    );
  }
}

usage

render() {
    <LoadingArea>
        ({ loading }) => {
            loading
                ? <Wating />
                : <Main />
        }
    </LoadingArea>
}

Similarly, when the final execution are JS, there is nothing strange.

React 16. * The new version of Conext.Consumer is the use of such an approach.

render() {
    <ThemeContext.Provider value={this.state.theme}>
      ...
        <ThemeContext.Consumer>
          {({theme}) => (
            <button
              style={{backgroundColor: theme.background}}>
              Toggle Theme
            </button>
          )}
        </ThemeContext.Consumer>
      ...
    </ThemeContext.Provider>    
}

Examples of recently developed again to share the benefits of component split.

Demand: countdown component development, operating configuration countdown time, the countdown initialization time acquisition from the server, before the end of countdown, after the operation to make the corresponding end of the countdown, the countdown of other components such as switching.

Component Split:

  • A container assembly business layer, is responsible for coordinating the processing business logic. (Overall planning, to do the countdown finished, you just told me)
  • A generic 'countdown' component, to a server system polling time, calculates the current remaining time, provided in the form FACC to children. (I count my sheep, you love Why Why)
  • A UI component countdown, the time remaining display and formatting UI. (How much rest time how come nothing to do with me, give me what I what to show)

Fake code:

// CountDownContainer.js
render() {
    const {
      endTime,
      renderSomethingAfterCountDown,
    } = this.props;

    return (
      <TimeLeftProvider endTime={endTime} >
        {seconds => (
          seconds > 0
            ? <CountDown {...this.props} remainingSeconds={seconds} />
            : renderSomethingAfterCountDown()
        )}
      </TimeLeftProvider>
    );
}
// TimeLeftProvider.js
export default class TimeLeftProvider extends PureComponent {
  static propTypes = {
    children: PropTypes.func,
    endTime: PropTypes.number,
  }

  // ...

  componentDidMount() {
    this.poll();
  }

  poll() {
    queryServerTime();
    this.pollTimer = setInterval(() => {
      queryServerTime();
    }, pollInterval * 1000);
  }

  countDown() {
    setInterval(() => {
      this.setState(prevState => ({
        remainingSeconds: prevState.remainingSeconds - 1,
      }));
    }, 1000);
  }

  render() {
    const { remainingSeconds, reliable } = this.state;
    return this.props.children(remainingSeconds, reliable);
  }
}
// CountDown.js

function CountDown(props) {
    const {
      remainingSeconds,
    } = props;
    const numbers = formatSeconds(remainingSeconds);
    const inputs = ['days', 'hours', 'minutes', 'seconds'];

    return (
      <div styleName={cls}>
        {
          inputs.map(key => ({
            label: key,
            number: numbers[key],
          })).map(
             //...
          )
        }
      </div>
    );
}

The final result was:

Count Down

at the same time

  • Clear code structure, their duties between components.
  • Strong component reusability.
  • Simple unit test, to test each component only its own logic.

Recommended Reading


More professional front-end knowledge, make the [2048] ape www.mk2048.com

Guess you like

Origin www.cnblogs.com/qianduanwriter/p/11758153.html