博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React学习(3)——列表、键值与表单
阅读量:6303 次
发布时间:2019-06-22

本文共 6920 字,大约阅读时间需要 23 分钟。

  hot3.png

本文记录了在官网学习如何使用JSX+ES6开发React的过程。 。

全文共分为3篇内容:

列表与组件的键值

    首先让我们看看在JavaScript中我们是如何处理一个列表的:

const numbers = [1, 2, 3, 4, 5];const doubled = numbers.map((number) => number * 2);console.log(doubled);

    例子中使用map方法将每个元素的值*2,最后得到的数组为:[2, 4, 6, 8, 10]。在React中,处理组件数组的方式与之类似。

渲染多个组件

    下面的例子,我们使用map()方法来创建组件中的一系列元素:

const numbers = [1, 2, 3, 4, 5];const listItems = numbers.map((number) =>  
  • {number}
  • );

        listItem就是一个包含多个<li>标签的组件。然后我们将listItem用<ul>标签包裹起来并在浏览器呈现:

    ReactDOM.render(  
      {listItems}
    , document.getElementById('root'));

        通过类似的方法,我们可以使用数组来创建一系列元素。

    基于列表的组件

        大部分情况,我们希望在一个组件中完成一个列表元素的渲染。将前面的例子稍加修改:

    //构建组件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'));

       当我们执行这个例子的代码时,会发现在浏览器中输出一个警告:" a key should be provided for list items"。"键值(Key)"在创建列表元素时是一个附加的属性,下一节会详细说明使用它的原因。

        通过number.map()方法向组建中的元素增加键值:

    function NumberList(props) {  const numbers = props.numbers;  const listItems = numbers.map((number) =>    //根据number输出设置li的key    
  • {number}
  • ); return (
      {listItems}
    );}const numbers = [1, 2, 3, 4, 5];ReactDOM.render(
    , document.getElementById('root'));

    键值的使用

        在React中,键值(keys)用来标记那些元素被修改了。在使用数组时,应该给数组元素标记键值以便于批量更新的效率:

    const numbers = [1, 2, 3, 4, 5];const listItems = numbers.map((number) =>  
  • {number}
  • );

        最好使用一个字符串来表示key值,并且确保兄弟节点之间的唯一性。例如使用业务id作为键值:

    const todoItems = todos.map((todo) =>  
  • {todo.text}
  • );

        在某些情况下无法获取到合理的id值,可以直接使用列表索引:

    const todoItems = todos.map((todo, index) =>  
  • {todo.text}
  • );

        如果列表中的元素可以重新排序,建议不要使用索引作为键值,这样会导致渲染缓慢。如果你对键值(keys)的使用有浓厚的兴趣,参看:。

    使用键值扩展组件

        键值仅仅在最外层列表中存在意义。例如,如果想抽取出一个名为ListItem的组件,最好在<ListItem />上标记key值,而不是组件中的<li>元素上。

        下面是一些错误使用键值的例子:

    function ListItem(props) {  const value = props.value;  //不应该在这里使用键值  return (    
  • {value}
  • );}function NumberList(props) { const numbers = props.numbers; /**建议在这里使用并标记键值*/ const listItems = numbers.map((number) =>
    ); return (
      {listItems}
    );}const numbers = [1, 2, 3, 4, 5];ReactDOM.render(
    , document.getElementById('root'));

        正确使用键值的例子:

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

    键值需要与兄弟节点保证唯一

        在使用的过程中,键值只要保证和兄弟节点的键值没有碰撞即可,并不需要全局唯一。在不同的列表中我们可以使用相同的key:

    function Blog(props) {  const sidebar = (    
      {props.posts.map((post) =>
    • {post.title}
    • )}
    ); const content = props.posts.map((post) =>

    {post.title}

    {post.content}

    ); return (
    {sidebar}

    {content}
    );}const posts = [ {id: 1, title: 'Hello World', content: 'Welcome to learning React!'}, {id: 2, title: 'Installation', content: 'You can install React from npm.'}];ReactDOM.render(
    , document.getElementById('root'));

        在上面的例子中sidebar、content是两个不同的队列,但是使用了相同的key值。

        键值虽然显示的设置到元素或组件上,但是并不能在组件内部直接获取,如果需要使用键值,我们需要另外设置:

    const content = posts.map((post) =>  
    );

        这样,在Post组件中可以通过this.props.id获取到id值,而this.props.key获取不到任何值。

    将map()方法嵌入到JSX中

        在下面的例子中,我们直接在map()方法中生成ListItem:

    function NumberList(props) {  const numbers = props.numbers;  const listItems = numbers.map((number) =>    
    ); return (
      {listItems}
    );}

        JSX允许在大括号"{}"中嵌入任何表达式,因此我们可以直接嵌入map()方法使用:

    function NumberList(props) {  const numbers = props.numbers;  return (    
      {numbers.map((number) =>
      )}
    );}

    表单

        因为表单元素都保持着一些内部状态,所以HTML的表单与React的表单工作方式有一些区别。例如在标准的HTML表单只接收单个名称:

        在用户提交表单时,浏览器默认会跳转到新的页面,当然在默认情况下React中的表单也是这样工作的。但是在大多数情况下,在用户提交数据到后台之前需要使用JavaScript来验证某些数据的合法性。实现这一点的方法我们称之为“controlled components(受控组件)”。

    受控组件

        在HTML中,<input><textarea>, and <select> 这些表单元素都包含自己的状态,并在用户输入时发生改变。而在React中,可变的状态通常保存在state属性值中,并且只能通过setState来改变。

        我们使用“受控组件”将2者合并,负责渲染表单的React组件还需要控制用户在渲染完毕后的各种输入操作。看下面这个例子:

    class NameForm extends React.Component {  constructor(props) {    super(props);    this.state = {value: ''};    this.handleChange = this.handleChange.bind(this);    this.handleSubmit = this.handleSubmit.bind(this);  }  handleChange(event) {    this.setState({value: event.target.value});  }  handleSubmit(event) {    alert('A name was submitted: ' + this.state.value);    event.preventDefault();  }  render() {    return (      
    ); }}

        例子中通过在onChange中注册this.handleChange方法来记录值的改变,在改变时会通过setState()设置this.state值,并使用render渲染。此外,组件还用this.handleSubmit来拦截提交事件。这个例子中的组件称之为"受控组件"。

        在受控组件中,每一个状态值的改变都会有一个相关处理函数来处理,这样可以直接修改或验证用户的输入。例如下面这个例子,我们将所有的输入强行变成大写:

    handleChange(event) {  this.setState({value: event.target.value.toUpperCase()});}

    textarea标签

        在HTML中,<textarea>由其子元素来定义文本:

        在React中,<textarea>使用一个value属性来代替子元素。这样使用<textarea>标签与使用单行输入元素(<input type="text">)类似:

    class EssayForm extends React.Component {  constructor(props) {    super(props);    this.state = {      value: 'Please write an essay about your favorite DOM element.'    };    this.handleChange = this.handleChange.bind(this);    this.handleSubmit = this.handleSubmit.bind(this);  }  handleChange(event) {    this.setState({value: event.target.value});  }  handleSubmit(event) {    alert('An essay was submitted: ' + this.state.value);    event.preventDefault();  }  render() {    return (      

        在这里例子中,在构造函数就初始化了this.state.value。因此<textarea>会显示一个初始值。

    select标签

        在HTML中,select会创建一个下拉菜单,例如:

        由于"cocount"设置了selected属性,所以默认状态下这个<option>是被选中的。在React中,<select>元素使用value元素来设定这个默认值,这在受控组件中使用更方便,因为只需要在一个地方更新它:

    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('Your favorite flavor is: ' + this.state.value);    event.preventDefault();  }  render() {    return (      
    ); }}

    受控组件的替代方案

        在某些情况下使用受控组件会非常的繁琐,因为它针对所有的变更都需要编写一个处理器来管理对应的状态。React官网推荐使用"非受控组件"技术来解决这个问题—— ,它是用于实现输入表单的替代技术。

    原文地址:https://www.chkui.com/article/react/react_list_key_and_form

    转载于:https://my.oschina.net/chkui/blog/796466

    你可能感兴趣的文章
    【图论算法】Dijstra&BFS
    查看>>
    注册和上传文件(头像)
    查看>>
    使用OVS
    查看>>
    键盘回收的几种方法
    查看>>
    Python(条件判断和循环)
    查看>>
    day4 linux安装python
    查看>>
    LeetCode Container With Most Water (Two Pointers)
    查看>>
    vue (v-if show 问题)
    查看>>
    https基础
    查看>>
    css3 canvas之刮刮卡效果
    查看>>
    并查集模板
    查看>>
    RESTful Mongodb
    查看>>
    BZOJ3237:[AHOI2013]连通图(线段树分治,并查集)
    查看>>
    如何提高Ajax性能
    查看>>
    Android--自定义加载框
    查看>>
    LINUX下 lamp安装及配置
    查看>>
    BZOJ3105 [cqoi2013]新Nim游戏
    查看>>
    困惑的前置操作与后置操作
    查看>>
    SDNU 1269.整数序列(水题)
    查看>>
    BZOJ 2118 Dijkstra
    查看>>