React学习(1):描述界面

学习参考官方文档:https://beta.reactjs.org/learn/keeping-components-pure

1. 第一个组件

React将界面分为一个个组件,从而更好的复用这些组件,使开发更便捷。

1.1 定义组件

export default function Profile(){
    return (
        <img src='test.jpg' alt='cute cat'/>
    );
}
  • 第一步导出组件,这样就可以在其他地方使用
    export default
  • 第二步定义函数,React组件本质上是一个普通的JavaScript函数
    function Profile(){}
  • 第三步添加样式,组件返回值是一段组件展示内容,这种语法叫做JSX
    return ()

1.2 使用组件

定义一个Gallery组件,它用到了Profile组件。可以说Gallery组件是Profile组件的父组件之一。

export default function Gallery(){
    return (
        <section>
        <h1>Amazing scientists</h1>
        <Profile />
        <Profile />
        </section>
    );
}

当定义了Profile组件之后,可以在其他地方使用很多次。定义了Gallery组件之后,还有更大的组件可以使用gallery组件。

2. 导入和导出组件

import Gallery from './Gallery.js';
export default function App(){
    return (
        <Gallery />
    );
}
exportimport
Defaultexport default function Button(){}import Button from './button.js;
Namedexport function Button(){}import {Button} from './button.js

3. 关于JSX

JSX从形式上看是在JavaScript文件内加入渲染的内容。JSX把渲染逻辑和渲染内容放在一个地方。
JSX的语法规则:

3.1 返回一个根元素
return(
  <div>
  ...
  </div>
);

或者

return(
  <>
  ...
  </>
);
3.2 标签闭合
<img src=''/>
<ul>
  <li>The moon</li>
<ul/>
3.3 属性名写法变为驼峰式
<img className="photo"/>
3.4 当使用js变量时加上大括号
const name = 'Alice';
return(
  <h1>{name}'s to do list</h1>
);
function formatDate(date){
  return new Intl.DateTimeFormat(
    'en-US', {weekday:'long'}
  ).format(date);
}

export default function TodoList(){
  return (
    <h1> To do List for {formatDate(tody)}</h1>
  );
}
3.5 CSS或其他对象使用{{}}
export default function TodoList(){
  return (
    <ul style={{ backgroundColor:'black', color:'pink'}}>
      <li>reading</li>
      <li>writing</li>
    </ul>
  );
}

4. 传递参数给组件

父组件可以通过给props到子组件传递信息给子组件。

4.1传递props给子组件
export default function Profile(){
  return (
    <Avatar person={{name:'Lin ye',imageId:'d2dhi3'}} size={100}>
  );
}
4.2在子组件中读取props
function Avatar({person, size = 100}){  //give default value for size
  // person size are available here
  return (
    <img src={getImageUrl(person) alt={person.name} width={size} height={size}}/>
  );
}
function Avatar({person, size}){
  //...
}

这种写法实际上是js的解构赋值,详见:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_a_function_parameter
它等效于:

function Avatar(props){
  let person = props.person;
  let size = props.size;
}
4.3转发props(forwarding props)
function Profile(props){
  return (
    <div className="card">
      <Avatar {...props} /> {/*更加优雅的方式转发全部参数*/}
    </div>
  );
}
4.4传递JSX作为子组件
function Card({children}){
  return (
    <div>
    {children}
    </div>
  );
}
export default function Profile(){
  return (
    <Card>
    <Avatar size={100}/>
    </Card>
  );
}

5.条件渲染

  • if/else
function Item({name, isPacked}){
  if(isPacked){
    return null;
  }
  return <li className="item">{name}</li>
}
  • operator(?: )
return (
  <li className="item">
  {isPacked ? name + '√':name}
  </li>
);
  • LogicalAND operator(&&)
return(
  <li className="item">
  {name} {isPacked && '√'}
  </li>
);

6. 渲染列表

6.1 从数组数据到列表
const people = [
  'johnson:math', 'mario:chemist', 'salam:physicist'
];
// map the people members into a new array of JSX nodes
const listItems = people.map(person => <li>{person}</li>);
// return listItems from components wrapped in a <ul>
return <ul>{listItems}</ul>;

这样实现会遇到报错:Each child in a list should have a unique “key” prop.
给list加上key值:

<li key={person.id}>...</li>
6.2 过滤
const chemists = people.filter(person =>
  person.profession === 'chemist'
);
6.3 关于key
  • 如何获取key值
    数据来自数据库:可以使用数据库 keys/IDs
    本地生成数据:crypto.randomUUID()等等

7. 保持组件纯粹

对于编程而言,一个纯粹的函数(pure function)具有以下特点:

  • 只处理自己的事情。
  • 同样的输入应得到同样的输出。
7.1 副作用(side effects):预期(非预期)结果

以下是个错误例子:

let guest = 0;
function Cup(){
  guest = guest+1;
  return <h2>Tea cup for guest #{guest}</h2>
}
export default function TeaSet(){
  return (
    <>
    <Cup/>  {/*Tea cup for guest #2 */}
    <Cup/>  {/*Tea cup for guest #4 */}
    </>
  );
}

在这个例子中,多次调用Cup组件会产生不同结果。如果有其他的组件读取guest的值,也将产生不同的JSX。
使用props改正:

function Cup({guest}){
  return <h2>Tea cup for guest #{guest}</h2>
}
export default function TeaSet(){
  return (
    <>
    <Cup guest={1}/>  {/*Tea cup for guest #1 */}
    <Cup guest={2}/>  {/*Tea cup for guest #2 */}
    </>
  );
}
7.2 局部改变

在上一个例子中,问题在于在渲染前改变了之前已经存在的变量。
但是,改变在渲染中创建的变量或是对象是可行的,例如:

function Cup({guest}){
  return <h2>Tea cup for guest #{guest}</h2>
}
export default function TeaSet(){
  let cups = [];
  for(let i = 0; i<=12; i++){
    cups.push(<Cup key={i} guest={i} />);
  }
  return cups;
}
7.3 什么地方可以引起副作用(side effects)

更新屏幕、开始动画、改变数据都称为side effects。

  • event handlers:当执行某些事件操作时才运行的函数,不在渲染过程中运行,不需要纯粹。
  • useEffect:在渲染后运行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值