zoukankan      html  css  js  c++  java
  • React-组件新增、扩展与使用

    prop 父传子

    React 应用中,数据通过 props 的传递,从父组件流向子组件
    Child 是一个 React 组件类,或者说是一个 React 组件类型。

    一个组件接收一些参数,我们把这些参数叫做 props(“props” 是 “properties” 简写),然后通过 render 方法返回需要展示在屏幕上的视图的层次结构

    props.children
    
    class Child extends React.Component {
        render() {
            return (
            <button className=acceptValue" onClick={() => alert('click')}>
                父组件流向子组件的值为: {this.props.value}
            </button>
            );
        }
    }
    // 用法示例: <Child value="X" />
    
    class Father extends React.Component {
        renderChild(i) {
            return <Child value={i} />;
        }
    
        render() {
            return (
                <div>
                    <div className="provideValue"> {this.renderChild(0)}</div>
                </div>
            );
        }
    }
    

    state 来实现所谓“记忆”的功能。

    可以通过在React 组件的构造函数中设置 this.state 来初始化 statethis.state 应该被视为一个组件的私有属性。我们在 this.state 中存储当前每个方格(Child)的值,并且在每次方格被点击的时候改变这个值。

    首先,我们向这个 class 中添加一个构造函数,用来初始化 state

    JavaScript class 中,每次你定义其子类的构造函数时,都需要调用 super 方法。因此,在所有含有构造函数的的 React 组件中,构造函数必须以 super(props) 开头。

    class Child extends React.Component {
    +  constructor(props) {
    +    super(props);
    +    this.state = {
    +      value: null,
    +    };
    +  }
    
      render() {
        return (
    -      <button className="acceptValue" onClick={() => alert('click')}>
    +      <button
    +          className="acceptValue"
    +          onClick={() => this.setState({value: 'X'})}
    +      >
    -        {this.props.value}
    +        {this.state.value}
          </button>
        );
      }
    }
    
    class Father extends React.Component {
        renderChild(i) {
    +        return <Child/>;
        }
    
        render() {
            return (
                <div>
                    <div className="provideValue"> {this.renderChild(0)}</div>
                </div>
            );
        }
    }
    

    子组件的 state 数据提升至其共同的父组件当中保存

    当你遇到需要同时获取多个子组件数据,或者两个组件之间需要相互通讯的情况时,需要把子组件的 state 数据提升至其共同的父组件当中保存。之后父组件可以通过 props 将状态数据传递到子组件当中。这样应用当中所有组件的状态数据就能够更方便地同步共享了。

    class Child extends React.Component {
        render() {
            return (
    +            <button
    +                className="acceptValue"
    +                onClick={() => this.props.onClick()}
    +            >
                    {this.props.value}
    -               {this.state.value}
                </button>
            );
        }
    }
    
    class Father extends React.Component {
    +    constructor(props) {
    +        super(props);//在 JavaScript class 中,每次你定义其子类的构造函数时,都需要调用 super 方法。因此,在所有含有构造函数的的 React 组件中,构造函数必须以 super(props) 开头
    +        this.state = {
    +            values: Array(9).fill(null)
    +        };
    +    }
    
    +    handleClick(i){
    +        const values=this.state.values.slice();// .slice() 方法创建了 squares 数组的一个副本,而不是直接在现有的数组上进行修改.简化复杂的功能-不直接在数据上修改可以让我们追溯并复用游戏的历史记录;跟踪数据的改变;确定在 React 中何时重新渲染
    +        values[i]='X'
    +        this.setState({values:values});
    +    }
    
        renderChild(i) {
            return (
                <Child
    +                value={this.state.values[i]}
    +                onClick={() => this.handleClick(i)}
                />
            );
        }
    
        render() {
            return (
                <div>
                    <div className="provideValue">
                        {this.renderChild(0)}
                    </div>
                </div>
            );
        }
    }
    

    函数组件

    如果你想写的组件只包含一个 render 方法,并且不包含 state,那么使用函数组件就会更简单。

    我们不需要定义一个继承于 React.Component 的类,我们可以定义一个函数,这个函数接收 props 作为参数,然后返回需要渲染的元素。函数组件写起来并不像 class 组件那么繁琐,很多组件都可以使用函数组件来写。

    function Child(props) {
      return (
        <button className="acceptValue" onClick={props.onClick}>
          {props.value}
        </button>
      );
    }
    

    注意
    当我们把 Square 修改成函数组件时,我们同时也把 onClick={() => this.props.onClick()} 改成了更短的 onClick={props.onClick}(注意两侧都没有括号)。

    向事件处理程序传递参数

    在循环中,通常我们会为事件处理函数传递额外的参数。例如,若 id 是你要删除那一行的 ID,以下两种方式都可以向事件处理函数传递参数:

    <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
    <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
    

    在这两种情况下,React 的事件对象 e 会被作为第二个参数传递。如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。

    与运算符 &&

    function Mailbox(props) {
      const unreadMessages = props.unreadMessages;
      return (
        <div>
          <h1>Hello!</h1>
    +      {unreadMessages.length > 0 &&
    +        <h2>
    +          You have {unreadMessages.length} unread messages.
    +        </h2>
          }
        </div>
      );
    }
    
    const messages = ['React', 'Re: React', 'Re:Re: React'];
    ReactDOM.render(
      <Mailbox unreadMessages={messages} />,
      document.getElementById('root')
    );
    

    在 JavaScript 中,true && expression 总是会返回 expression, 而 false && expression 总是会返回 false

    因此,如果条件是 true&& 右侧的元素就会被渲染,如果是 false,React 会忽略并跳过它。

    三目运算符

    使用 JavaScript 中的三目运算符 condition ? true : false

    render() {
      const isLoggedIn = this.state.isLoggedIn;
      return (
        <div>
          {isLoggedIn ? (
            <LogoutButton onClick={this.handleLogoutClick} />
          ) : (
            <LoginButton onClick={this.handleLoginClick} />
          )}
        </div>
      );
    }
    

    就像在 JavaScript 中一样,你可以根据团队的习惯来选择可读性更高的代码风格。需要注意的是,如果条件变得过于复杂,那你应该考虑如何提取组件

    阻止组件渲染

    在极少数情况下,你可能希望能隐藏组件,即使它已经被其他组件渲染。若要完成此操作,你可以让 render 方法直接返回 null,而不进行任何渲染。

    下面的示例中, 会根据 prop 中 warn 的值来进行条件渲染。如果 warn 的值是 false,那么组件则不会渲染:

    function WarningBanner(props) {
    +  if (!props.warn) {
    +    return null;
    +  }
    
      return (
        <div className="warning">
          Warning!
        </div>
      );
    }
    
    class Page extends React.Component {
      constructor(props) {
        super(props);
        this.state = {showWarning: true};
        this.handleToggleClick = this.handleToggleClick.bind(this);
      }
    
      handleToggleClick() {
        this.setState(state => ({
          showWarning: !state.showWarning
        }));
      }
    
      render() {
        return (
          <div>
    +        <WarningBanner warn={this.state.showWarning} />
            <button onClick={this.handleToggleClick}>
              {this.state.showWarning ? 'Hide' : 'Show'}
            </button>
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <Page />,
      document.getElementById('root')
    );
    

    key

    当元素没有确定 id 的时候,万不得已你可以使用元素索引 index 作为 key:

    const todoItems = todos.map((todo, index) =>
      // Only do this if items have no stable IDs
      <li key={index}>
        {todo.text}
      </li>
    );
    

    如果列表项目的顺序可能会变化,我们不建议使用索引来用作 key 值,因为这样做会导致性能变差,还可能引起组件状态的问题。可以看看 Robin Pokorny 的深度解析使用索引作为 key 的负面影响这一篇文章。
    如果你选择不指定显式的 key 值,那么 React 将默认使用索引用作为列表项目的 key 值。

    表单

    class FlavorForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {value: 'coconut'};
    
    +    this.handleChange = this.handleChange.bind(this);
    +    this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleChange(event) {
    +    this.setState({value: event.target.value});
      }
    
      handleSubmit(event) {
        alert('你喜欢的风味是: ' + this.state.value);
    +    event.preventDefault();
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              选择你喜欢的风味:
    +          <select value={this.state.value} onChange={this.handleChange}>
                <option value="grapefruit">葡萄柚</option>
              </select>
            </label>
    
    +        <input type="submit" value="提交" />
          </form>
        );
      }
    }
    

    color{#f00}{!!!}你可以将数组传递到 value 属性中,以支持在 select 标签中选择多个选项:

    <select multiple={true} value={['B', 'C']}>
    

    注意点

    • 组件名称必须以大写字母开头。
    • componentDidMount() 方法会在组件已经被渲染到 DOM 中后运行
    • 构造函数是唯一可以给 this.state 赋值的地方,this.setState({});
    • 数据是向下流动的, state局部的或是封装的。除了拥有并设置了它的组件其他组件无法访问,组件可以选择把它的 state 作为 props 向下传递到它的子组件.这通常会被叫做“自上而下”或是“单向”数据流。任何的 state 总是所属于特定的组件,而且从该 state 派生的任何数据或 UI 只能影响树中“低于”它们的组件
    • React 事件的命名采用小驼峰式camelCase),而不是纯小写。
    • key 应该在数组的上下文中被指定.在 map() 方法中的元素需要设置 key 属性.key 只是在兄弟节点之间必须唯一
    • 如果你的组件中需要使用 key 属性的值,请用其他属性名显式传递这个值.无法通过props读出 props.key
    • JSX 允许在大括号中嵌入任何表达式
  • 相关阅读:
    陶瓷电容的结构、工艺、失效模式
    Vue.js最佳实践
    Vue 超快速学习
    CSS 小技巧
    HTML5 Canvas
    webkit下面的CSS设置滚动条
    Some untracked working tree files would be overwritten by checkout. Please move or remove them before you can checkout. View them
    JSCS: Please specify path to 'JSCS' package
    React中ref的使用方法
    React 60S倒计时
  • 原文地址:https://www.cnblogs.com/ajaemp/p/13634038.html
Copyright © 2011-2022 走看看