前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React 学习笔记(二)

React 学习笔记(二)

作者头像
子舒
发布2022-06-09 13:56:32
2.7K0
发布2022-06-09 13:56:32
举报
文章被收录于专栏:子舒的个人博客

React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同

React 事件的命名采用小驼峰式(camelCase),而不是纯小写

使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串

一、事件处理

1.事件绑定

React 元素的事件处理和 DOM 元素类似,但是在语法上有些区别,比如:

传统的html:用双引号包裹,后面必须跟参数

代码语言:javascript
复制
<button onclick="myfun()">点击</button>

React:用大括号包裹,后面不跟参数

代码语言:javascript
复制
<button onclick={myfun}>点击</button>

一个完整的事件函数代码如下

代码语言:javascript
复制
class Demo extends React.Component {
    render() {

        // 事件函数
        function myfun() {
            alert('helo,world')
        }

        return (
            // 绑定事件
            <button onClick={this.myfun}>
                Activate Lasers
            </button>
        )
    }
}

ReactDOM.render(
    <Demo />,
    document.getElementById('root')
)

如果方法后面没有(),则需要为这个方法绑定 this

2.阻止默认行为

在 React 中还有一个不同的点,不能通过返回 fasle 阻止默认行为, React 提供了一个属性--preventDefault,可以通过 preventDefault 阻止脚本执行

看一下传统的 html 和 React 的对比

代码语言:javascript
复制
<a href="#" onclick="alert('是否弹窗?');return false">
    Click me
</a>

直接在写上 false 就可以阻止脚本执行

React 通过 preventDefault 属性阻止脚本执行:

代码语言:javascript
复制
function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

二、条件渲染

在 React 中,可以创建不同的组件来封装各种你需要的行为,然后,根据应用不同的状态,你可以只渲染对应状态下的部分内容。

React 中的条件渲染和 javascript 中的一样,使用 if 运算符来表示元素当前的状态,然后让 React 根据他们来更新 UI。

使用 if..else 语句进行条件渲染

先写一个条件渲染的例子,定义了两个组件,然后通过判断组件 Greeting 中的变量 isLoggedIn 的真伪,让浏览器渲染组件 UserGreeting 或者 GuestGreeting

代码语言:javascript
复制
// App.js
import React, { Component } from 'react'

export default class App extends Component {
  render() {
    function UserGreeting(props) {
      return <h3>Welcome back!</h3>;
    }

    function GuestGreeting(props) {
      return <h3>Please sign up.</h3>;
    }

    function Greeting(props) {
      const isLoggedIn = props.isLoggedIn;
      if (isLoggedIn) {
        return <UserGreeting />;
      }   
      return <GuestGreeting />;
    }

    return (
      <div>
        <Greeting isLoggedIn={false} />
      </div>
    )
  }
}

最后变量 isLoggedIn 定义了 false,因此,浏览器渲染 `GuestGreeting。

怎么阻止条件渲染?

在有些情况下,我们希望能隐藏组件,即使他已经被其他组件渲染。我们可以通过 render 方法返回 null 让组件不渲染。

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

代码语言:javascript
复制
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')
);

三、渲染列表

先看一段代码,我们使用 map() 函数让数组中的每一项变双倍,然后得到一个新的数组 doubled 并打印出来。

代码语言:javascript
复制
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);

// [2,4,6,8,10]

而在 React 中,把数组转换为元素列表的过程是相似的。

先通过 map() 方法遍历 numbers 数组,将数组中的每个元素变成 <li> 标签,最后将得到的数组赋值给 listItems

然后返回 {listItem}

代码语言:javascript
复制
// Map.js
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}</li>
);

ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('root')
);

运行之后浏览器出现 1-5 的无序列表

1.分离组件

上面就是一个基本的列表渲染的例子,但是数据写死了。接下来我们将数组重构成一个组件,以后再进行数组渲染时,可以轻松调用。

代码语言:javascript
复制
// Map.js
export default class Map extends Component {
  render() {

  // 分离出组件 NumberList 作为转换数组的组件
    function NumberList(props) {
      const numbers = props.numbers;
      const listItems = numbers.map((number) =>
        <li>{number}</li>
      );
      return (
        <ul>{listItems}</ul>
      );
    }

    // 传入需要的数据
    const numbers = [1, 2, 3, 4, 5, 6, 7];

    return (
      <div>
        <NumberList numbers={numbers} />
      </div>
    )
  }
}

2.key

运行代码之后,页面会正常显示,但是控制台会报一个错误。Each child in a list should have a unique "key" prop.,意思是当你创建一个元素时,必须包括一个特殊的 key 属性。

现在给每个列表元素分配一个key:

代码语言:javascript
复制
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

3.使用 id 作为 key

key 帮助 React 识别了哪些元素被改变,比如删除和添加,所以应当给每个元素确定一个标识,也就是 key

一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串。通常,我们使用数据中的 id 来作为元素的 key

代码语言:javascript
复制
// Map.js
export default class Map extends Component {
  render() {

    function NumberList(props) {
      const numbers = props.numbers;
      const listItems = numbers.map((number) =>
        <li key={number.id}>  // 赋值 key
          {number.text}
        </li>
      );
      return (
        <ul>{listItems}</ul>
      );
    }

    // 传入数据
    const numbers = [
      {id: 1,text: 1},
      {id: 2,text: 2},
      {id: 3,text: 3},
      {id: 4,text: 4},
      {id: 5,text: 5}
    ];

    return (
      <Fragment>
        <NumberList numbers={numbers} />
      </Fragment>
    )
  }
}

4.索引 index 可以作为 key 吗?

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

代码语言:javascript
复制
const todoItems = todos.map((todo, index) =>
  // 仅仅当没有确定 id 的时候使用索引index作为 key
  <li key={index}>
    {todo.text}
  </li>
);

如果列表项目的顺序可能会变化,我们不建议使用索引来用作 key 值,因为这样做会导致性能变差,还可能引起组件状态的问题。

5.用 key 提取组件

比方说,如果你提取出一个 ListItem 组件,你应该把 key 保留在数组中的这个 <ListItem /> 元素上,而不是放在 ListItem 组件中的 <li> 元素上。

错误的使用方法:

代码语言:javascript
复制
function ListItem(props) {
  const value = props.value;
  return (
    // 错误!你不需要在这里指定 key:
    <li key={value.toString()}>
      {value}
    </li>
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 错误!元素的 key 应该在这里指定:
    <ListItem value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

正确的使用方法:

代码语言:javascript
复制
function ListItem(props) {
  // 正确!这里不需要指定 key:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 正确!key 应该在数组的上下文中被指定
    <ListItem key={number.toString()}              value={number} />

  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

React:一个好的经验法则是:在 map( ) 方法中的元素需要设置 key 属性。

6.key 只是在兄弟节点之间必须唯一

数组元素中使用的 key 在其兄弟节点之间应该是独一无二的。然而,它们不需要是全局唯一的。当我们生成两个不同的数组时,我们可以使用相同的 key 值:

代码语言:javascript
复制
function Blog(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}
      <hr />
      {content}
    </div>
  );
}

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(
  <Blog posts={posts} />,
  document.getElementById('root')
);

7.vue 中渲染列表

Vue 中渲染列表使用的是特殊指令 v-for,其中也有 key 的相关用法

React 中采用的是 map() 方法遍历数组,然后渲染列表

title: React 学习笔记(二) date: 2020-12-16 13:15:00 updated: 2021-11-09 15:19:31 categories:

  • 技术

tags:

  • react

React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同

React 事件的命名采用小驼峰式(camelCase),而不是纯小写

使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串

一、事件处理

1.事件绑定

React 元素的事件处理和 DOM 元素类似,但是在语法上有些区别,比如:

传统的html:用双引号包裹,后面必须跟参数

代码语言:javascript
复制
<button onclick="myfun()">点击</button>

React:用大括号包裹,后面不跟参数

代码语言:javascript
复制
<button onclick={myfun}>点击</button>

一个完整的事件函数代码如下

代码语言:javascript
复制
class Demo extends React.Component {
    render() {

        // 事件函数
        function myfun() {
            alert('helo,world')
        }

        return (
            // 绑定事件
            <button onClick={this.myfun}>
                Activate Lasers
            </button>
        )
    }
}

ReactDOM.render(
    <Demo />,
    document.getElementById('root')
)

如果方法后面没有(),则需要为这个方法绑定 this

2.阻止默认行为

在 React 中还有一个不同的点,不能通过返回 fasle 阻止默认行为, React 提供了一个属性--preventDefault,可以通过 preventDefault 阻止脚本执行

看一下传统的 html 和 React 的对比

代码语言:javascript
复制
<a href="#" onclick="alert('是否弹窗?');return false">
    Click me
</a>

直接在写上 false 就可以阻止脚本执行

React 通过 preventDefault 属性阻止脚本执行:

代码语言:javascript
复制
function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

二、条件渲染

在 React 中,可以创建不同的组件来封装各种你需要的行为,然后,根据应用不同的状态,你可以只渲染对应状态下的部分内容。

React 中的条件渲染和 javascript 中的一样,使用 if 运算符来表示元素当前的状态,然后让 React 根据他们来更新 UI。

使用 if..else 语句进行条件渲染

先写一个条件渲染的例子,定义了两个组件,然后通过判断组件 Greeting 中的变量 isLoggedIn 的真伪,让浏览器渲染组件 UserGreeting 或者 GuestGreeting

代码语言:javascript
复制
// App.js
import React, { Component } from 'react'

export default class App extends Component {
  render() {
    function UserGreeting(props) {
      return <h3>Welcome back!</h3>;
    }

    function GuestGreeting(props) {
      return <h3>Please sign up.</h3>;
    }

    function Greeting(props) {
      const isLoggedIn = props.isLoggedIn;
      if (isLoggedIn) {
        return <UserGreeting />;
      }   
      return <GuestGreeting />;
    }

    return (
      <div>
        <Greeting isLoggedIn={false} />
      </div>
    )
  }
}

最后变量 isLoggedIn 定义了 false,因此,浏览器渲染 `GuestGreeting。

怎么阻止条件渲染?

在有些情况下,我们希望能隐藏组件,即使他已经被其他组件渲染。我们可以通过 render 方法返回 null 让组件不渲染。

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

代码语言:javascript
复制
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')
);

三、渲染列表

先看一段代码,我们使用 map() 函数让数组中的每一项变双倍,然后得到一个新的数组 doubled 并打印出来。

代码语言:javascript
复制
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);

// [2,4,6,8,10]

而在 React 中,把数组转换为元素列表的过程是相似的。

先通过 map() 方法遍历 numbers 数组,将数组中的每个元素变成 <li> 标签,最后将得到的数组赋值给 listItems

然后返回 {listItem}

代码语言:javascript
复制
// Map.js
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}</li>
);

ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('root')
);

运行之后浏览器出现 1-5 的无序列表

1.分离组件

上面就是一个基本的列表渲染的例子,但是数据写死了。接下来我们将数组重构成一个组件,以后再进行数组渲染时,可以轻松调用。

代码语言:javascript
复制
// Map.js
export default class Map extends Component {
  render() {

  // 分离出组件 NumberList 作为转换数组的组件
    function NumberList(props) {
      const numbers = props.numbers;
      const listItems = numbers.map((number) =>
        <li>{number}</li>
      );
      return (
        <ul>{listItems}</ul>
      );
    }

    // 传入需要的数据
    const numbers = [1, 2, 3, 4, 5, 6, 7];

    return (
      <div>
        <NumberList numbers={numbers} />
      </div>
    )
  }
}

2.key

运行代码之后,页面会正常显示,但是控制台会报一个错误。Each child in a list should have a unique "key" prop.,意思是当你创建一个元素时,必须包括一个特殊的 key 属性。

现在给每个列表元素分配一个key:

代码语言:javascript
复制
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

3.使用 id 作为 key

key 帮助 React 识别了哪些元素被改变,比如删除和添加,所以应当给每个元素确定一个标识,也就是 key

一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串。通常,我们使用数据中的 id 来作为元素的 key

代码语言:javascript
复制
// Map.js
export default class Map extends Component {
  render() {

    function NumberList(props) {
      const numbers = props.numbers;
      const listItems = numbers.map((number) =>
        <li key={number.id}>  // 赋值 key
          {number.text}
        </li>
      );
      return (
        <ul>{listItems}</ul>
      );
    }

    // 传入数据
    const numbers = [
      {id: 1,text: 1},
      {id: 2,text: 2},
      {id: 3,text: 3},
      {id: 4,text: 4},
      {id: 5,text: 5}
    ];

    return (
      <Fragment>
        <NumberList numbers={numbers} />
      </Fragment>
    )
  }
}

4.索引 index 可以作为 key 吗?

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

代码语言:javascript
复制
const todoItems = todos.map((todo, index) =>
  // 仅仅当没有确定 id 的时候使用索引index作为 key
  <li key={index}>
    {todo.text}
  </li>
);

如果列表项目的顺序可能会变化,我们不建议使用索引来用作 key 值,因为这样做会导致性能变差,还可能引起组件状态的问题。

5.用 key 提取组件

比方说,如果你提取出一个 ListItem 组件,你应该把 key 保留在数组中的这个 <ListItem /> 元素上,而不是放在 ListItem 组件中的 <li> 元素上。

错误的使用方法:

代码语言:javascript
复制
function ListItem(props) {
  const value = props.value;
  return (
    // 错误!你不需要在这里指定 key:
    <li key={value.toString()}>
      {value}
    </li>
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 错误!元素的 key 应该在这里指定:
    <ListItem value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

正确的使用方法:

代码语言:javascript
复制
function ListItem(props) {
  // 正确!这里不需要指定 key:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 正确!key 应该在数组的上下文中被指定
    <ListItem key={number.toString()}              value={number} />

  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

React:一个好的经验法则是:在 map( ) 方法中的元素需要设置 key 属性。

6.key 只是在兄弟节点之间必须唯一

数组元素中使用的 key 在其兄弟节点之间应该是独一无二的。然而,它们不需要是全局唯一的。当我们生成两个不同的数组时,我们可以使用相同的 key 值:

代码语言:javascript
复制
function Blog(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}
      <hr />
      {content}
    </div>
  );
}

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(
  <Blog posts={posts} />,
  document.getElementById('root')
);

7.vue 中渲染列表

Vue 中渲染列表使用的是特殊指令 v-for,其中也有 key 的相关用法

React 中采用的是 map() 方法遍历数组,然后渲染列表

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020 年 12 月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、事件处理
    • 1.事件绑定
      • 2.阻止默认行为
      • 二、条件渲染
        • 使用 if..else 语句进行条件渲染
          • 怎么阻止条件渲染?
          • 三、渲染列表
            • 1.分离组件
              • 2.key
                • 3.使用 id 作为 key
                  • 4.索引 index 可以作为 key 吗?
                    • 5.用 key 提取组件
                      • 6.key 只是在兄弟节点之间必须唯一
                        • 7.vue 中渲染列表
                        • 一、事件处理
                          • 1.事件绑定
                            • 2.阻止默认行为
                            • 二、条件渲染
                              • 使用 if..else 语句进行条件渲染
                                • 怎么阻止条件渲染?
                                • 三、渲染列表
                                  • 1.分离组件
                                    • 2.key
                                      • 3.使用 id 作为 key
                                        • 4.索引 index 可以作为 key 吗?
                                          • 5.用 key 提取组件
                                            • 6.key 只是在兄弟节点之间必须唯一
                                              • 7.vue 中渲染列表
                                              领券
                                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档