react学习笔记-基础知识

props

  1. 在函数式组件里面, 使用传参的形式拿到props
  2. 在es6 class语法里面, 使用this.props拿到 props
  3. props是只读属性
function Welcome(props) {
  return 

Hello, {props.name}

; } function App() { return (
); }

ES6 class写法

class Welcome extends React.Component {
  render() {
    return 

Hello, {this.props.name}

; } }

生命周期

  1. componentDidMount 组件挂载完毕

  2. componentWillUnmount 组件即将卸载

state


  constructor(props) {
    super(props);
    this.state = {date: new Date()};  // 定义一个state
  }


  1. 注意事项:
this.state.comment = 'Hello';  // 此代码不会重新渲染组件:

|
| 正确使用方式
| --------------->

this.setState({comment: 'Hello'});
  1. 注意事项2

this.props为异步获取数据, this.state也可能是异步获取数据, 当props或state数据改变, 可能会导致数据不会更新

this.setState({
  counter: this.state.counter + this.props.increment,
});

|
| 正确使用方式
| --------------->

this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));

|
| 或正确使用方式
| --------------->

this.setState(function(prevState, props) {
  return {
    counter: prevState.counter + props.increment
  };
});

事件绑定

  1. 基础例子:

  1. 注意事项:
  • 不能 return false的方式 阻止默认行为 必须明确的使用 preventDefault
function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }
  return (
    
      Click me
    
  );
}

  1. 绑定this
    JSX 回调函数中的 this,类的方法默认是不会绑定 this 的, this 的值会是 undefined。

解决方法1: 在constructor 中显示的为 函数 使用 Bind方法绑定this

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
    this.handleClick = this.handleClick.bind(this);  // 这里绑定了this
  }
  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }
  render() {
    return (
      
    );
  }
}
ReactDOM.render(
  ,
  document.getElementById('root')
);

解决方法2: 函数使用es6箭头函数的方式声明

  handleClick = () => {
    console.log('this is:', this);
  }

解决方法3:


解决方法4:


条件渲染

1.在方法内部使用if/else

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return ;
  }
  return ;
}
ReactDOM.render(
  // Try changing to isLoggedIn={true}:
  ,
  document.getElementById('root')
);
  1. 在render内部使用判断语句
render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button = null;
    if (isLoggedIn) {
      button = 
我是组件1我是组件2 {button}
); } }
  1. 使用与运算符 &&
function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    

Hello!

{unreadMessages.length > 0 &&

You have {unreadMessages.length} unread messages.

}
); }
  1. 三目运算符
render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    
The user is {isLoggedIn ? 'currently' : 'not'} logged in.
); }

|
|
| 或这样
------------->

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    
{isLoggedIn ? ( ) : ( )}
); }
  1. 阻止组件渲染
function WarningBanner(props) {
  if (!props.warn) {
    return null;
  }

  return (
    
Warning!
); }

map渲染

循环的时候记得加key

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    
  • {number}
  • ); return (
      {listItems}
    ); } const numbers = [1, 2, 3, 4, 5]; ReactDOM.render( , document.getElementById('root') );

    keys 与组件

    1. 被循环的根组件内添加key
    2. 数组元素中使用的key在其兄弟之间应该是独一无二的。然而,它们不需要是全局唯一的
      return (
        // 错啦!你不需要在这里指定key:
        
  • {value}
  • ); const listItems = numbers.map((number) => //错啦!元素的key应该在这里指定: );

    |
    |
    | 正确使用
    |-------》

    function ListItem(props) {
      // 对啦!这里不需要指定key:
      return 
  • {props.value}
  • ; } const listItems = numbers.map((number) => // 又对啦!key应该在数组的上下文中被指定 );

    JSX允许在大括号中嵌入任何表达式,

      return (
        
      {numbers.map((number) => )}
    );

    受控组件

    1. input
    • 使用value={this.state.value}绑定数据, 然后通过change事件修改state.value数据
    class NameForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {value: ''};
        this.handleChange = this.handleChange.bind(this);
      }
    
      handleChange(event) {
        this.setState({value: event.target.value});
      }
    
      render() {
        return (
              
        );
      }
    }
    
    
    
    
    1. textarea

    textarea标签的使用方式跟Input一样, 不同的是, 在react中, textarea会用value属性来代替

    1. select

    Coconut选项最初由于selected属性是被选中的。在React中,并不使用之前的selected属性,而在根select标签上用value属性来表示选中项

    
    
    1. input file标签

    由于该标签的 value 属性是只读的, 所以它是 React 中的一个非受控组件。

    组件交互(状态提升)

    //------------------------  父组件
    class Calculator extends React.Component {
      constructor(props) {
        super(props);
        this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
        this.state = {temperature: ''};
      }
        // 注册方法
      handleCelsiusChange(temperature) {
        this.setState({temperature});
      }
      render() {
        const celsius = this.state.temperature;
        return (
          
    ); } } //------------------------ 子组件 class TemperatureInput extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } // 触发父组件传递过来的参数的方法, 吧值传递回去 handleChange(e) { this.props.onTemperatureChange(e.target.value); } render() { const temperature = this.props.temperature; return (
    // 接收到父组件传递过来的参数, 并赋值给自己
    ); } }

    props.children 子代

    通过props.children渲染组件内的内容

    1. 渲染内部所有内容
    function FancyBorder(props) {
      return (
        
    {props.children}
    ); } function WelcomeDialog() { return (

    Welcome

    Thank you for visiting our spacecraft!

    ); }
    1. 内部内容指定渲染位置
    function SplitPane(props) {
      return (
        
    {props.left}
    {props.right}
    ); } function App() { return ( } right={ } /> ); }

    jsx与react

    1. react组件与react调用
    
      Click Me
    
    

    |
    | 转换
    |----->

    React.createElement(
      MyButton,
      {color: 'blue', shadowSize: 2},
      'Click Me' // 当使用自闭合标签(
    ) 的时候, 里面是没有内容的,可以使用Null放在这里 )
    1. 点表示法
      也可以使用对象的形式作为组件
    import React from 'react';
    const MyComponents = {
      DatePicker: function DatePicker(props) {
        return 
    Imagine a {props.color} datepicker here.
    ; } } function BlueDatePicker() { return ; }
    1. 首字母大写
    import React from 'react';
    // 正确!组件名应该首字母大写:
    function Hello(props) {
      // 正确!div 是有效的 HTML 标签:
      return 
    Hello {props.toWhat}
    ; } function HelloWorld() { // 正确!React 能够将大写开头的标签名认为是 React 组件。 return ; }
    1. 组件变量
    
    
    import React from 'react';
    import { PhotoStory, VideoStory } from './stories';
    
    const components = {
      photo: PhotoStory,
      video: VideoStory
    };
    
    function Story(props) {
      // 正确!JSX 标签名可以为大写开头的变量。
      const SpecificStory = components[props.storyType];
      return ;
      //-------------------------------
      // 错误!JSX 标签名不能为一个表达式。
        return ;
    }
    
    
    1. 属性中的表达式

    你可以传递任何 {} 包裹的 JavaScript 表达式作为一个属性值

    
    

    if 语句和 for 循环在 JavaScript 中不是表达式,因此它们不能直接在 JSX 中使用,但是你可以将它们放在周围的代码中。

    function NumberDescriber(props) {
      let description;
      if (props.number % 2 == 0) {
        description = even;
      } else {
        description = odd;
      }
      return 
    {props.number} is an {description} number
    ; }
    • 字符串常量
    
    =========
    
    
    • 默认为 True
    
    =======
    
    
    • 扩展属性
    function App2() {
      const props = {firstName: 'Ben', lastName: 'Hector'};
      return ;
    }
    
    • 渲染时, 布尔值, Null, undefined 被忽略, 下面的都等价
    {false}
    {null}
    {undefined}
    {true}

    propTypes检测类型

    1. 限制类型
    import PropTypes from 'prop-types';
    class Greeting extends React.Component {
      render() {
        return (
          

    Hello, {this.props.name}

    ); } } Greeting.propTypes = { name: PropTypes.string };

    具体验证例子请打开该链接
    https://react.docschina.org/docs/typechecking-with-proptypes.html

    1. 限制单个子代
    
    
    import PropTypes from 'prop-types';
    
    class MyComponent extends React.Component {
      render() {
        // This must be exactly one element or it will warn.
        const children = this.props.children;
        return (
          
    {children}
    ); } } MyComponent.propTypes = { children: PropTypes.element.isRequired };
    1. 属性默认值
    
    // 为属性指定默认值:
    Greeting.defaultProps = {
      name: 'Stranger'
    };
    

    refs

    • 你不能在函数式组件上使用 ref 属性
    • ref 的更新会发生在componentDidMount 或 componentDidUpdate 生命周期钩子之前
      使用 React.createRef() 创建 refs,通过 ref 属性来获得 React 元素
    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
        this.myRef = React.createRef();
      }
      render() {
        return 
    ; } }
    1. 通过this.myRef.current 拿到dom元素
    class CustomTextInput extends React.Component {
      constructor(props) {
        super(props);
        // 创建 ref 存储 textInput DOM 元素
        this.textInput = React.createRef();
        this.focusTextInput = this.focusTextInput.bind(this);
      }
    
      focusTextInput() {
        // 直接使用原生 API 使 text 输入框获得焦点
        // 注意:通过 "current" 取得 DOM 节点
        this.textInput.current.focus();
      }
    
      render() {
        // 告诉 React 我们想把  ref 关联到构造器里创建的 `textInput` 上
        return (
          
    ); } }
    1. 回调 Refs
    class CustomTextInput extends React.Component {
      constructor(props) {
        super(props);
        this.textInput = null;
        // 这里的回调 把当前元素赋值给this.textInput
        this.setTextInputRef = element => {
          this.textInput = element;
        };
    
        this.focusTextInput = () => {
          // 直接使用原生 API 使 text 输入框获得焦点
          if (this.textInput) this.textInput.focus();
        };
      }
    
      componentDidMount() {
        // 渲染后文本框自动获得焦点
        this.focusTextInput();
      }
    
      render() {
        // 使用 `ref` 的回调将 text 输入框的 DOM 节点存储到 React
        // 实例上(比如 this.textInput)
        return (
          
    ); } }

    非受控组件

    1. 基础用法
    class NameForm extends React.Component {
      constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
      handleSubmit(event) {
        alert('A name was submitted: ' + this.input.value);
        event.preventDefault();
      }
      render() {
        return (
          
    ); } }
    1. 默认值 defaultValue

    你希望 React 可以为其指定初始值,但不再控制后续更新。 你可以指定一个 defaultValue 属性而不是 value
    同样, 支持 defaultChecked,