react模式(上)

react模式(模式的定义,我认为是类似于一种规范,一种方法,你可以用其他的方法去实现,但这些是已有的,总结的,相对使用可靠方便的方法)
借鉴于在网上的react模式,我觉得按照模式编程会事半功倍,因此总结如下:

### 函数组件 (Function component)

函数组件 是最简单的一种声明可复用组件的方法

他们就是一些简单的函数。
```jsx
function Greeting() {
 return <div>Hi there!</div>;
}

从第一个形参中获取属性集 (props)

function Greeting(props) {
  return <div>Hi {props.name}!</div>;
}
```
按自己的需要可以在函数组件中定义任意变量
最后一定要返回你的 React 组件。
```jsx
function Greeting(props) {
  let style = {
    fontWeight: "bold",
    color: context.color
  };
  return <div style={style}>Hi {props.name}!</div>;
}
```
使用 defaultProps 为任意必有属性设置默认值
```jsx
function Greeting(props) {
  return <div>Hi {props.name}!</div>;
}
Greeting.defaultProps = {
  name: "Guest"
};
```
个人总结:最简单的可复用组件,例如你想用某个小部分写成组件时,可以不必新建页面,而直接使用函数组件将会明了简单的多

### 属性解构 (Destructuring props)

解构赋值 是一种 JavaScript 特性。
出自 ES2015 版的 JavaScript 新规范。
所以看起来可能并不常见。
好比字面量赋值的反转形式。
```
let person = { name: "chantastic" };
let { name } = person;
```
同样适用于数组。
```
let things = ["one", "two"];
let [first, second] = things;
```
解构赋值被用在很多 函数组件 中。

下面声明的这些组件是相同的。
```jsx
function Greeting(props) {
  return <div>Hi {props.name}!</div>;
}

function Greeting({ name }) {
  return <div>Hi {name}!</div>;
}
```
有一种语法可以在对象中收集剩余属性。

叫做 剩余参数,看起来就像这样。
```jsx
function Greeting({ name, ...restProps }) {
  return <div>Hi {name}!</div>;
}
```
那三个点 (...) 会把所有的剩余属性分配给 restProps 对象

然而,你能使用 restProps 做些什么呢?

继续往下看...

个人总结:了解let arr={};  let {elements} =arr;将会取出arr.elements即为解构赋值,加上大括号即可,另外了解(...)以及剩余属性restProps 对象

### JSX 中的属性展开 (JSX spread attributes)
属性展开是 JSX 中的一个的特性。

它是一种语法,专门用来把对象上的属性转换成 JSX 中的属性

参考上面的 属性解构,
我们可以 扩散 restProps 对象的所有属性到 div 元素上
```jsx
function Greeting({ name, ...restProps }) {
  return <div {...restProps}>Hi {name}!</div>;
}
```
这让 Gretting 组件变得非常灵活。

我们可以通过传给 Gretting 组件 DOM 属性并确定这些属性一定会被传到 div 上

<Greeting name="Fancy pants" className="fancy-greeting" id="user-greeting" />
避免传递非 DOM 属性到组件上。 解构赋值是如此的受欢迎,是因为它可以分离 组件特定的属性 和 DOM/平台特定属性
```jsx
function Greeting({ name, ...platformProps }) {
 return <div {...platformProps}>Hi {name}!</div>;
}
```

个人总结:JSX 中的属性展开会使对象的属性像数组一样展开

### 合并解构属性和其它值 (Merge destructured props with other values)
组件就是一种抽象。
好的抽象是可以扩展的。
比如说下面这个组件使用 class 属性来给按钮添加样式。
```jsx
function MyButton(props) {
  return <button className="btn" {...props} />;
}
```
一般情况下这样做就够了,除非我们需要扩展其它的样式类

`<MyButton className="delete-btn">Delete...</MyButton>`

在这个例子中把 btn 替换成 delete-btn

JSX 中的属性展开 对先后顺序是敏感的

扩散属性中的 className 会覆盖组件上的 className。

我们可以改变它两的顺序,但是目前来说 className 只有 btn。
```
function MyButton(props) {
  return <button {...props} className="btn" />;
}
```
我们需要使用解构赋值来合并入参 props 中的 className 和基础的(组件中的) className。 可以通过把所有的值放在一个数组里面,然后使用一个空格连接它们。
```jsx
function MyButton({ className, ...props }) {
  let classNames = ["btn", className].join(" ");

  return <button className={classNames} {...props} />;
}
为了保证 undefined 不被显示在 className 上,可以使用 默认值。

function MyButton({ className = "", ...props }) {
  let classNames = ["btn", className].join(" ");

  return <button className={classNames} {...props} />;
}
```
个人总结:可以写组件时很好的用到该功能,比如写完利用该功能某些组件,可以对 该组件设置classname以达到自定义组件样式的问题,而不需要知道该组件到底有哪些固定样式等等,可以很好地解决一些兼容性的问题,比如button的一些组件,除非我看完其组件的源代码,否则无法知道如何将其改为红色,或者别的颜色


### 条件渲染 (Conditional rendering)
不可以在一个组件声明中使用 if/else 语句 You can't use if/else statements inside a component declarations.
所以可以使用 条件(三元)运算符 和 短路计算。
```jsx
如果
{
  condition && <span>Rendered when `truthy`</span>;
}
除非
{
  condition || <span>Rendered when `falsy`</span>;
}
如果-否则
{
  condition ? (
    <span>Rendered when `truthy`</span>
  ) : (
    <span>Rendered when `falsy`</span>
  );
}
```
个人总结:这一点在react中经常用到,render方法里面写jsx常常为难一些条件判断是否展示该dom ,或者是展示哪个dom时,该模式可以巧妙解决

### 子元素类型 (Children types)
很多类型都可以做为 React 的子元素。

多数情况下会是 数组 或者 字符串。

### 字符串 String
`<div> Hello World! </div>`

个人:字符串将会直接展示

### 数组 Array 
`<div>{["Hello ", <span>World</span>, "!"]}</div>`

个人:数组在jsx将会展开,该结果应该展示为`<div>Hello <span> world </span> !</div>`

### 数组做为子元素 (Array as children)
将数组做为子元素是很常见的。
列表是如何在 React 中被绘制的。
我们使用 map() 方法创建一个新的 React 元素数组
```jsx
<ul>
  {["first", "second"].map(item => (
    <li>{item}</li>
  ))}
</ul>
这和使用字面量数组是一样的。

<ul>{[<li>first</li>, <li>second</li>]}</ul>
这个模式可以联合解构、JSX 属性扩散以及其它组件一起使用,看起来简洁无比

<ul>
  {arrayOfMessageObjects.map(({ id, ...message }) => (
    <Message key={id} {...message} />
  ))}
</ul>
```

个人:当jsx中需要遍历生成dom时经常使用数组map生成dom数组,也可以直接使用字面量数组,相对简洁


### 函数做为子元素 (Function as children)
React 组件不支持函数类型的子元素。

然而 渲染属性 是一种可以创建组件并以函数作为子元素的模式。

### 渲染属性 (Render prop)
这里有个组件,使用了一个渲染回调函数 children。

这样写并没有什么用,但是可以做为入门的简单例子。

const Width = ({ children }) => children(500);
组件把 children 做为函数调用,同时还可以传一些参数。上面这个 500 就是实参。

为了使用这个组件,我们可以在调用组件的时候传入一个子元素,这个子元素就是一个函数。

<Width>{width => <div>window is {width}</div>}</Width>
我们可以得到下面的输出。

<div>window is 500</div>
有了这个组件,我们就可以用它来做渲染策略。

<Width>
  {width => (width > 600 ? <div>min-width requirement met!</div> : null)}
</Width>
如果有更复杂的条件判断,我们可以使用这个组件来封装另外一个新组件来利用原来的逻辑。

const MinWidth = ({ width: minWidth, children }) => (
  <Width>{width => (width > minWidth ? children : null)}</Width>
);
显然,一个静态的 Width 组件并没有什么用处,但是给它绑定一些浏览器事件就不一样了。下面有个实现的例子。
```jsx
class WindowWidth extends React.Component {
  constructor() {
   super();
    this.state = { width: 0 };
  }

  componentDidMount() {
    this.setState(
      { width: window.innerWidth },
      window.addEventListener("resize", ({ target }) =>
        this.setState({ width: target.innerWidth })
      )
    );
  }

  render() {
    return this.props.children(this.state.width);
  }
}
```
许多开发人员都喜欢 高阶组件 来实现这种功能。但这只是个人喜好问题。

个人总结:这两点不是很清楚 请教一下别人


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值