React数据流

React数据流,第1张

在 React 中,数据是自顶而下单向流动的,即从父组件到子组件。

React的数据传输主要靠state和props来完成。如果顶层组件初始化 props,那么 React 会向下遍历整棵组件树,重新尝试渲染所有相关的子组件。state 只关心每个组件自己内部的状态,这些状态只能在组件内变化。把组件看成一个函数,那么它接收了 props 作为参数,内部由 state 作为函数的内部参数,返回一个 Virtual DOM 的实现。

state中往往储存一些时刻变化的变量或者后期可能要更新的参数。我们用setState()方法来更新state中的值。

下面是一个计数的例子,通过点击更新按钮,触发setState()方法,使state中的值发生改变。

props往往用来定义一些静态的常量,或者用于父子组件间的通信。props本身是不可变的,当我们试图改变props中的原始值,React会报出类型错误的警告。

React提供的获取DOM元素的方法有两种,一是react-dom中的findDOMNode(),二是refs。

findDOMNode通常用于React组件的引用,其语法如下:

当组件被渲染到DOM中后,findDOMNode会返回该组件实例对应的DOM节点。

示例:

注:如果render()中返回null,那么findDOMNode()也返回null。findDOMNode只对已经挂载的组件有效。

refs多用于React组件内子组件的引用。使用ref获取DOM节点有两种情况:

(1)子组件为原生DOM组件:获取到的就是这个DOM节点。如下例,thisinput就获取到了当前 <input /> 节点。

通过thismyInput,我就可以对 <input /> 进行一系列 *** 作,比如让输入框聚焦:

注:refs也支持字符串格式:

通过thisrefsmyInput获取到节点。

(2)子组件为React组件,比如 <MyInput/> :获得的就是 <MyInput/> 的实例,因此就可以调用 <MyInput/> 的实例方法。

示例:

注:调用 <Comp /> 实例方法的方式:thisrefsmyCompmethod(),但并不建议这种调用方式。

React 在组件间传递数据的确比较恼火。目前基本上只有通过 props 来传递。所以你必须在 button 和 listitem 共有的父组件上设置 state,再通过传递这个父组件定义事件处理函数来更新状态,通过状态更新来触发子组件的更新……好复杂的样子,还是看 jsfiddle 吧

常用的ajax请求库

相关文档: >

方法一:导出 store

这应该是最简单省事同时也容易想到的方法,但是有一点需要注意:

不要在服务端渲染中使用该方法

如果你在使用服务端渲染的 app 中直接导出 store,那么 app 的所有 user 都会获得一个单例的 store (包括相同的 JWT Token),这肯定不是你乐见的。

除去上述这种情况,当我们需要获取 store 中的 JWT Token 时,可以这么做:

/

storejs

/

import { createStore } from 'redux';

import reducer from '/reducer';

const store = createStore(reducer);

export default store;

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

创建 store 的方法还和以前一样,仅仅是导出它,以便于在其他文件中使用。

不要担心你使用的 createStore 方法可能会很复杂,放心的使用各种中间件比如 thunk, saga, devtools ,你需要做的仅仅是导出 store 而已。

紧接着,在需要用到 store 中数据的地方,引入 (import) 它。下面的例子就是我们在一个普通函数 apijs 中将 store 中的 JWT Token 通过 ajax 传递给服务端。

/

apijs

/

import store from '/store';

export function getProtectedThing() {

// grab current state

const state = storegetState();

// get the JWT token out of it

// (obviously depends on how your store is structured)

const authToken = statecurrentUsertoken;

// Pass the token to the server

return fetch('/user/thing', {

method: 'GET',

headers: {

Authorization: `Bearer ${authToken}`

}

})then(res => resjson());

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

在 Redux 官网的 FAQ 中有这样一个问题 我可以在组件中直接引入 store 并使用吗 ?

其实如果需要在 React 组件中使用 store,我们有更好的选择 (译者注:也是官方提倡的):那就是使用 React-Redux 中的 connect 方法。

Mark Erikson,Redux 的维护者之一,在 Reddit 上就这个问题发表过如下看法:

通常情况下,不建议在 component 中通过 import 的方式来使用 store

在某些情况下,可以试着通过 thunk 或者其他一些 Redux 中间件来 *** 作 store 而不是直接去引用它。

但是凡事总有例外,打我自己的比方,有一个项目中 70% 的代码使用 Backbone 写的,在项目的一些模块中,我们同时需要来自 Backbone models 和 Redux store 中的数据,在这部分模块中,我们的确需要 import {store} from “store” 这种直接的引用方式,因为我们的确没有其他选择。

所以,直接引用并不是理想的方式,但是,如果有必要,也可以。

React Component 之外 dispatch action

如果你在 React Component 之外需要 dispatch action,那么同样的方法也是适用的:引入 store 然后再调用 storedispatch(),这和你在 react-redux 中通过 connect 函数获取到 dispatch 是一样的。

方法二:从 thunk 中获取 redux 的 state

如果你需要在 thunk 中获取 redux store 中的某项数据,更简单不过。你根本不需要直接引入 store,因为 thunk 的 action 中有一个 getState 的输入参数。

下面的例子就是从 thunk 的 action 创建函数中获取 JWT Token

/ actionsjs /

export function getProtectedThing() {

return (dispatch, getState) => {

// grab current state

const state = getState();

// get the JWT token out of it

// (obviously depends on how your store is structured)

const authToken = statecurrentUsertoken;

// Pass the token to the server

return fetch('/user/thing', {

method: 'GET',

headers: {

Authorization: `Bearer ${authToken}`

}

})then(res => resjson());

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

另外,如果你不想在 thunk 的 action 函数中直接使用 fetch,你可以选择将 fetch 封装到另外一个类中比如 apijs 当然你需要额外的参数将所需数据传递出去。

方法三:使用中间件(middleware)截获 action 中的数据

如果你不喜欢上述两种方法 (或是无法使用),那么也可以试试下面这种方法。

开发一个自定义的 redux 中间件,“拦截” 特定的 action 在 action 触达 store 之前获取其携带的数据,甚至在中间件中直接获取 store

我们还以 JWT Token 为例。假设应用程序在用户成功登陆后会触发一个 LOG_SUCCESS 的 action,该 action 携带的数据包含 JWT Token

/

indexjs

/

const saveAuthToken = store => next => action => {

if(actiontype === 'LOGIN_SUCCESS') {

// after a successful login, update the token in the API

apisetToken(actionpayloadauthToken);

}

// continue processing this action

return next(action);

}

const store = createStore(

reducer,

applyMiddleware(saveAuthToken)

);

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

在你的 apijs 中会有一个 setToken 的方法将 token 赋值给本地变量。

/

apijs

/

let currentAuthToken = null;

export function setToken(token) {

currentAuthToken = token;

}

export function getProtectedThing() {

// Pass the token to the server

return fetch('/user/thing', {

method: 'GET',

headers: {

Authorization: `Bearer ${currentAuthToken}`

}

})then(res => resjson());

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

如果你使用的 >

React Query 因其极大地简化了 React 应用程序中的数据获取而受到许多人的喜爱。但是它并不是数据获取库,它应该叫 异步状态管理器 ,它可以管理任何形式的异步状态——只要它得到一个 Promise。

从本质上讲,React Query 基于查询键值为您管理查询缓存。 只要键值是可序列化的,并且对查询的数据来说。它是唯一的,就可以使用它。虽然支持用字符串,但还是建议使用数组形式,因为内部最终还是会转化成数组。

React Query 很聪明,它会选择策略点来触发重新获取数据。

数据转换也是前端经常遇到的问题,因为API返回的数据可能不是我们刚好能用的,react-query也提供了转换器,并且也只在有数据的时候才会被调用。

因为每次渲染都会执行,如果转换数据的方法开销比较大,建议使用useCallback将select函数缓存起来。

初始化数据,也就是数据没有缓存时直接展示的内容,当缓存中有该数据时,则不会生效。

NextJS在React-Query的使用

react没有提供自己的请求数据的模块,笔者以axios和fetch-jsonp为例来请求数据。

一、axios

1、安装axios模块

2使用

二、fetch-jsonp

1、安装 npm install fetch-jsonp --save

以上就是关于React数据流全部的内容,包括:React数据流、React中获取DOM节点的两种方法、react 怎么通过api拿数据等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9669693.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存