如何添加 1 个 React 组件的 JS 状态变量以用于其他组件?
Posted
技术标签:
【中文标题】如何添加 1 个 React 组件的 JS 状态变量以用于其他组件?【英文标题】:How do I add a JS state variable of 1 React component for use in other components? 【发布时间】:2021-12-29 11:52:20 【问题描述】:我有一个 Home.js 组件,它让用户注册 API 并登录,然后获取从响应授权标头接收到的令牌并将其保存在 state 'token' 变量中。
此令牌将在所有其他组件中用于在发出请求时访问 API,那么将此值用于所有其他组件的最佳方式是什么?
Home.js:
const SIGNUP_URL = 'http://localhost:8080/users/signup';
const LOGIN_URL = 'http://localhost:8080/login';
class Home extends Component
constructor(props)
super(props);
this.state =
isAuthenticated:false,
token: ''
;
componentDidMount()
const payload =
"username": "hikaru",
"password": "JohnSmith72-"
;
fetch(SIGNUP_URL,
method: 'POST',
headers:
"Accept": "application/json",
"Content-Type": "application/json"
,
body: JSON.stringify(payload)
)
.then(response => response.json())
.then((data) =>
console.log(data);
);
fetch(LOGIN_URL,
method: 'POST',
headers:
"Accept": "application/json",
"Content-Type": "application/json"
,
body: JSON.stringify(payload)
)
.then(response =>
this.setState(token: response.headers.get("Authorization"), isAuthenticated:true)
)
例如 userList 组件将从 API 中获取用户数据,但需要存储在 Home 组件的令牌状态变量中的 API 令牌才能通过授权标头成功发送请求。
感谢您的帮助
【问题讨论】:
【参考方案1】:例如,您可以创建一个名为 authenticated_request
的自定义函数。这个函数可以从 CookieStorage 中获取你的令牌,如果是 web 或者异步存储,如果是 react-native 或者即使你有它在一些状态管理库中。没关系。使用此函数而不是 fetch
函数并在其中调用 fetch。将其视为您的网络请求的高阶函数。
const authenticated_request(url, config)
fetch(url,
...config,
headers:
...config.headers,
Authorization: getToken()
);
您还可以利用 axios 之类的东西,并使用请求拦截器来拦截请求和响应。根据需要注入您的令牌。
【讨论】:
【参考方案2】:您应该使用 AuthContext 和 localStorage 来执行此操作,将令牌保存在 state 或 localStorage 中,并制作一个配置文件,在调用我在 axios 中完成的 api 时使用相同的令牌。 Axios 有一个拦截器的概念,它允许我们将令牌附加到我们的 api 调用,我在成功登录后将令牌保存在 localStorage 中,然后使用 localStorage 中的相同令牌添加到需要令牌的每个调用,如果 api 不需要一个token(有些api可以是公开的)我可以直接用axios,看看下面的代码:
import axios from 'axios';
let apiUrl = '';
let imageUrl = '';
if(process.env.NODE_ENV === 'production')
apiUrl = `$process.env.REACT_APP_LIVE_URL_basePath/web/v1/`;
else
apiUrl = `http://127.0.0.1:8000/web/v1/`;
const config =
baseURL: apiUrl,
headers:
'Content-Type': 'application/json;charset=UTF-8',
"Access-Control-Allow-Origin": "https://www.crazyforstudy.com",
'Access-Control-Allow-Methods': 'GET, POST, PATCH, DELETE',
,
;
const authAxios = axios.create(config);
authAxios.interceptors.request.use(async function(config)
config.headers.Authorization = localStorage.getItem('access_token') ?
`Bearer $localStorage.getItem('access_token')` :
``;
return config;
);
export apiUrl, axios, authAxios ;
现在在进行 api 调用时,您可以执行以下操作:
import apiUrl, authAxios from '../config/config'
export async function saveAssignment(data)
try
const res = await authAxios.post(apiUrl + 'assignment/save-assignment', data)
return res.data;
catch(e)
这里注意我不是使用 axios 进行 api 调用,而是使用 authAxios 进行调用(从配置文件中导出),这将在标头中有令牌。
(您也可以使用 Redux 等第三方库,但概念保持不变)
【讨论】:
【参考方案3】:您需要一个集中的状态,这就是 状态管理 库的用途。您可以使用 Redux 等第三方库,也可以直接使用 React 自己的 context。你可以在 google 上搜索 React 的状态管理,你会发现很多有用的资源
【讨论】:
【参考方案4】:如果您的应用是 s-s-r,您可以将令牌放入 cookie。为此,您必须创建以下函数:
export const eraseCookie = (name) =>
document.cookie = `$name=; Max-Age=-99999999;`;
;
export const getCookie = (name) =>
const pairs = document.cookie.split(';');
const pair = pairs.find((cookie) => cookie.split('=')[0].trim() === name);
if (!pair) return '';
return pair.split('=')[1];
;
export const setCookie = (name, value, domain) =>
if (domain)
document.cookie = `$name=$value;path=/`;
else
document.cookie = `$name=$value`;
;
您也可以将令牌放入本地存储:
通过内置函数设置到本地存储:
localStorage.setItem('token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c');
通过内置函数获取令牌:
const token = localStorage.getItem('token');
【讨论】:
以上是关于如何添加 1 个 React 组件的 JS 状态变量以用于其他组件?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React.js 的另一个组件中更新组件状态变量的值?
React 应用程序变慢并且 JS Heap 变大。如何发现内存泄漏?