在 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拿数据等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)