• React 7


    7.86 Deeper into Components and React Internals

    import React, { Component } from 'react';
    import './App.css';
    
    
    import Persons from '../components/Persons/Persons';
    import Cockpit from '../components/Cockpit/Cockpit';
    
    
    //use as many as function components as possible
    //containers be as lean as possible
    
    
    class App extends Component {
      state = {
        persons: [
          {id:'1', name: 'Max', age: 28 },
          {id:'2', name: 'Manu', age: 29 },
          {id:'3', name: 'Stephanie', age: 26 }
        ],
          otherState: 'some other value',
          showPersons: false
    
      }
    
      switchNameHandler = (newName) => {
        // console.log('Was clicked!');
        // DON'T DO THIS: this.state.persons[0].name = 'Maximilian';
        this.setState( {
          persons: [
            {name: newName, age: 28 },
            {name: 'Manu', age: 29 },
            {name: 'Stephanie', age: 27 }
          ]
        } )
      }
    
        nameChangedHandler = (event, id) => {
            const personIndex = this.state.persons.findIndex(p => {
                return p.id === id;//这个看不懂
    
    
            });
    
            const person = { ...this.state.persons[personIndex] };
    
            person.name = event.target.value;
    
            const persons = [...this.state.persons];
            persons[personIndex] = person;
    
            this.setState({
                persons: persons
            });
      }
    
        togglePersonsHandler = () => {
    
            const doesShow = this.state.showPersons;
            this.setState({showPersons: !doesShow});
    
        }
    
        deletePersonHandler = (personIndex) => {
            const persons = this.state.persons.slice();
            //const persons = [...this.state.persons];
            persons.splice(personIndex, 1);
            this.setState({ persons: persons });///bhb
    
        }
    
        render() {
            
    
            let persons = null;
            if(this.state.showPersons){
                persons = <Persons
                            persons={this.state.persons}
                            clicked={this.deletePersonHandler}
                            changed={this.nameChangedHandler}
                        />
                    
                ;
    
    
    
        return (
          <div className="App">
                <Cockpit
                    showPersons={this.state.showPersons}
                    persons={this.state.persons}
                    clicked={this.togglePersonsHandler}
                />
                {persons}
              
          </div>
        );
        // return React.createElement('div', {className: 'App'}, React.createElement('h1', null, 'Does this work now?'));
      }
    }
    
    export default App;
    import React from 'react';
    //import '.../containers/App.css'
    import styled from 'styled-components';
    
    const cockpit = (props) => {
    
        const StyledButton = styled.button`
    
                background-color: ${props => props.alt ? 'red' : 'green'};
                color: white;
                font: inherit;
                border: 1px solid blue;
                padding: 8px;
                cursor: pointer;
                &:hover {
                    background-color: ${props => props.alt ? 'blue' : 'salmon'};
                    color: black;
                }
    
            `;
    
    
    
    
    
        let classes = [];
        if (props.persons.length <= 2) {
            classes.push('red');//push red 给这个array
        }
        if (props.persons.length <= 1) {
            classes.push('bold');
        }
    
    
        return (
            <div>
                <h1>Hi, I'm a React App</h1>
                <p className={classes.join(' ')}>This is really working!</p>
                <StyledButton alt={props.showPersons}
                    onClick={props.clicked}>Switch Name</StyledButton>
            </div>);
    
    };
    //报错:return multiple outputs without root node(用《div》括起来)
    export default cockpit;

     87 stateful stateless

    presentational state(stateless)a functional components dont use state

    index.js

    ReactDOM.render(<App appTitle="Person Manager"/>, document.getElementById('root'));

     

     

     89 class component lifecycle

     

     change functional component into class based component

    import React from 'react';
    /*import './Person.css';*/
    /*import Radium from 'radium';*/
    import styled from 'styled-components';
    
    
    const StyledDiv = styled.div`
    
    
        60%;
        margin:16px;
        border:1px solid #eee;
        box-shadow: 0 2px 3px #ccc;
        padding: 16px;
        text-align: center;
    
    
    
    
    `;
    
    const person = ( props ) => {
        return (
            /*<div className="Person">*/
                <StyledDiv>
                <p onClick={props.click}>I'm {props.name} and I am {props.age} years old!</p>
                <p>{props.children}</p>
                <input type="text" onChange={props.changed} value={props.name} />
            </StyledDiv>
        )
    };
    
    export default person;

    useEffect() in functional components

        useEffect(() => {
            console.log("cockpitjs useEffect");
    
        });

    useeffect 一直会render

    下面只有persons change了 才会rerender 如果是【】则只有第一次和unmount时生效

        useEffect(() => {
            console.log("cockpitjs useEffect");
    
            setTimeout(() => {
    
                alert("saved");
            }, 1000); 一秒后有个alert 测试用
        }, [props.persons]);//当什么元素执行的时候 如果数组里没有元素 则只有第一次render
    
        //useEffect(可以加其他的effect)

    return代表componentwillunmount 即这个组件被remove了那就会有console.log 但是除非它被remove 否则一直不会有log(在first render cycle 以后 但其他之前)

     return () => {
               /* clearTimeout(timer);*/
                console.log("cockpit js cleanup");//this is not shown because cockpit is never removed?           
    
    
            };

    搞清楚 real dom virtual dom  render

    7.97 class-based:shouldConponentUpdate

      shouldComponentUpdate(nextProps, nextState) {
            console.log("shouldComponentUpdate personjs");
            if (nextProps !== this.props) {
                return true;
            } else {
    
                return false;
            }

    如果有改动,就重新render

    7.98 Optimizing Functional Components
    with React.memo()

     if (props.personslength <= 1) {
            classes.push('bold');
        }
    export default React.memo(cockpit);

    if use memo  only rerender when props change

     there is no

     7.100

    import React, { Component} from 'react';
    
    import styled from 'styled-components';
    
    
    
    
    class Person extends Component {//大写class name
    
        static getDerivedStateFromProps(props, state) {
    
            console.log("getDerivedStateFromProps personjs");
            return state;
        }
    
        shouldComponentUpdate(nextProps, nextState) {
            console.log("shouldComponentUpdate personjs");
            if (nextProps !== this.props ||
                nextProps.changed !==this.props.changed
    
    
            ) {
                return true;
            } else {
    
                return false;
            }

    等于

    import React, { PureComponent} from 'react';
    /*import './Person.css';*/
    /*import Radium from 'radium';*/
    import styled from 'styled-components';
    
    
    
    
    class Person extends PureComponent {

    自带shouldComponentUpdate 查重所有props

    7.101

    102 Rendering Adjacent JSX Elements

    <Div>
                    <p onClick={this.props.click}>I'm {this.props.name} and I am {this.props.age} years old!</p>
                    <p>{this.props.children}</p>
                    <input type="text" onChange={this.props.changed} value={this.props.name} />
                </Div>//props前加上this

    ==

    <p key=“1” onClick={this.props.click}>I'm {this.props.name} and I am {this.props.age} years old!</p>,
                    <p key=“2”>{this.props.children}</p>,
                    <input key=“3” type="text" onChange={this.props.changed} value={this.props.name} />
    】

     

     

     HOC

     

     

     

     107 passing unknown props

    person.js

    import React, { Component } from 'react'; import Aux from '../../../hoc/Auxillary'; import withClass from '../../../hoc/withClass'; import classes from './Person.css'; class Person extends Component { render() { console.log('[Person.js] rendering...'); return ( <Aux> <p onClick={this.props.click}> I'm {this.props.name} and I am {this.props.age} years old! </p> <p key="i2">{this.props.children}</p> <input key="i3" type="text" onChange={this.props.changed} value={this.props.name} /> </Aux> ); } } export default withClass(Person, classes.Person);
    withClass.js


    import React from 'react'; const withClass = (WrappedComponent, className) => { return props => ( <div className={className}> <WrappedComponent {...props}/> </div> ); }; export default withClass;
    aux.js
    const aux = props => props.children; export default aux;

    108.setState correctly

     用这个而不是

     因为这个不能保证this.state是上一个state

    109:Using PropTypes

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    
    import Aux from '../../../hoc/Auxillary';
    import withClass from '../../../hoc/withClass';
    import classes from './Person.css';
    
    class Person extends Component {
      render() {
        console.log('[Person.js] rendering...');
        return (
          <Aux>
            <p onClick={this.props.click}>
              I'm {this.props.name} and I am {this.props.age} years old!
            </p>
            <p key="i2">{this.props.children}</p>
            <input
              key="i3"
              type="text"
              onChange={this.props.changed}
              value={this.props.name}
            />
          </Aux>
        );
      }
    }
    
    
    Person.propTypes = {
        click: PropTypes.func,
        name: PropTypes.string,
        age: PropTypes.number,
        changed: PropTypes.func
    
    
    };
    
    export default withClass(Person, classes.Person);

    类型检查,没有符合,加warning

    110 using ref

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    
    import Aux from '../../../hoc/Auxillary';
    import withClass from '../../../hoc/withClass';
    import classes from './Person.css';
    
    class Person extends Component {
        componentDidMount() {
            this.inputElement.focus();
    
        }
    
    
      render() {
        console.log('[Person.js] rendering...');
        return (
          <Aux>
            <p onClick={this.props.click}>
              I'm {this.props.name} and I am {this.props.age} years old!
            </p>
            <p key="i2">{this.props.children}</p>
            <input
                    key="i3"
                    ref={(inputEl) => {this.inputElement=inputEl }}
              type="text"
              onChange={this.props.changed}
              value={this.props.name}
            />
          </Aux>
        );
      }
    }
    
    
    Person.propTypes = {
        click: PropTypes.func,
        name: PropTypes.string,
        age: PropTypes.number,
        changed: PropTypes.func
    
    
    };
    
    export default withClass(Person, classes.Person);

    111 ref with react hook

    import React, { useEffect,useRef } from 'react';
    
    import classes from './Cockpit.css';
    
    const Cockpit = props => {
        const toggleBtnRef = React.createRef(null);
        /*toggleBtnRef.current.click();*/
    
      useEffect(() => {
        console.log('[Cockpit.js] useEffect');
        // Http request...
        /*setTimeout(() => {
          alert('Saved data to cloud!');
        }, 1000);*/
          toggleBtnRef.current.click();
        return () => {
          console.log('[Cockpit.js] cleanup work in useEffect');
        };
      }, []);
    
      useEffect(() => {
        console.log('[Cockpit.js] 2nd useEffect');
        return () => {
          console.log('[Cockpit.js] cleanup work in 2nd useEffect');
        };
      });
    
      // useEffect();
    
      const assignedClasses = [];
      let btnClass = '';
      if (props.showPersons) {
        btnClass = classes.Red;
      }
    
      if (props.personsLength <= 2) {
        assignedClasses.push(classes.red); // classes = ['red']
      }
      if (props.personsLength <= 1) {
        assignedClasses.push(classes.bold); // classes = ['red', 'bold']
      }
    
      return (
        <div className={classes.Cockpit}>
          <h1>{props.title}</h1>
          <p className={assignedClasses.join(' ')}>This is really working!</p>
              <button ref={toggleBtnRef} className={btnClass} onClick={props.clicked}>
            Toggle Persons
          </button>
        </div>
      );
    };
    
    export default React.memo(Cockpit);

    不能放在上面 放在上面 渲染时候下面jsx代码还没有渲染 会报错,故放在useffect里 在render结束后发生

    functional component只能用这个react hook

  • 相关阅读:
    1.28
    1.27
    1.26
    如果给你以下功能怎么测试
    测试面试题
    对h5页面的测试方式
    完美解决linux下Django报错Error: That port is already in use.
    KeyError:使用Python的Appium中的“ touchAction” 错误码
    Appium自动化测试
    selenium IDE使用
  • 原文地址:https://www.cnblogs.com/cschen588/p/12420092.html
Copyright © 2020-2023  润新知