React 抱怨下面的代码,说它 useEffect 被有条件地调用:
import React, { useEffect, useState } from 'react'
import VerifiedUserOutlined from '@material-ui/icons/VerifiedUserOutlined'
import withStyles from '@material-ui/core/styles/withStyles'
import firebase from '../firebase'
import { withRouter } from 'react-router-dom'
function Dashboard(props) {
const { classes } = props
const [quote, setQuote] = useState('')
if(!firebase.getCurrentUsername()) {
// not logged in
alert('Please login first')
props.history.replace('/login')
return null
}
useEffect(() => {
firebase.getCurrentUserQuote().then(setQuote)
})
return (
<main>
// some code here
</main>
)
async function logout() {
await firebase.logout()
props.history.push('/')
}
} …Run Code Online (Sandbox Code Playgroud)正如文档中所述,useCallback返回一个memoized回调.
传递内联回调和一组输入.useCallback将返回一个回忆的memoized版本,该版本仅在其中一个输入发生更改时才会更改.这在将回调传递给优化的子组件时非常有用,这些子组件依赖于引用相等性来防止不必要的渲染(例如,shouldComponentUpdate).
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
Run Code Online (Sandbox Code Playgroud)
但是它如何工作以及在React中最好使用它?
我第一次尝试React钩子,所有看起来都很好,直到我意识到当我获取数据并更新两个不同的状态变量(数据和加载标志)时,我的组件(数据表)呈现两次,即使两个调用状态更新程序正在发生在同一个函数中.这是我的api函数,它将两个变量都返回给我的组件.
const getData = url => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(async () => {
const test = await api.get('/people')
if(test.ok){
setLoading(false);
setData(test.data.results);
}
}, []);
return { data, loading };
};
Run Code Online (Sandbox Code Playgroud)
在普通的类组件中,你只需要调用一次来更新可以是一个复杂对象的状态,但是"钩子方式"似乎是将状态分成更小的单元,其副作用似乎是多个在单独更新时呈现.任何想法如何缓解这个?
是否可以使用 afunction作为我的 React 组件的状态?
示例代码在这里:
// typescript
type OoopsFunction = () => void;
export function App() {
const [ooops, setOoops] = React.useState<OoopsFunction>(
() => console.log('default ooops')
);
return (
<div>
<div onClick={ ooops }>
Show Ooops
</div>
<div onClick={() => {
setOoops(() => console.log('other ooops'))
}}>
change oops
</div>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用......defaultOoops将在最开始时调用,当单击时change oops,otrher ooops将立即记录到控制台,Show Ooops再次单击后不会记录。
为什么 ?
我可以使用函数作为组件的状态吗?
或者 React 有其特殊的处理方式the function state?
我需要连接到 WebSockets 服务器并记录它的消息。使用 React 类组件,我会将这个逻辑放在componentDidMount生命周期钩子中并愉快地继续,但我不确定如何使用钩子正确实现它。
这是我的第一次尝试。
import React, {useEffect} from 'react';
export default function AppWs() {
useEffect(() => {
let ws = new WebSocket('wss://ws.kraken.com/');
ws.onopen = () => console.log('ws opened');
ws.onclose = () => console.log('ws closed');
ws.onmessage = e => {
const message = JSON.parse(e.data);
console.log('e', message);
};
return () => {
ws.close();
}
}, []);
return (
<div>hooks + ws</div>
)
}
Run Code Online (Sandbox Code Playgroud)
我向 中添加了连接和日志逻辑useEffect,提供了带有依赖项的空数组,并且一切正常。直到我需要添加pause状态以暂停日志记录。
export default function AppWs() {
const [isPaused, setPause] = …Run Code Online (Sandbox Code Playgroud) 我正在尝试学习钩子,而useState方法使我感到困惑。我正在将初始值分配给数组形式的状态。即使使用spread(...)或,useState中的set方法对我也不起作用without spread operator。我在另一台PC上制作了一个API,我正在调用它并提取要设置为状态的数据。
这是我的代码:
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
const StateSelector = () => {
const initialValue = [
{
category: "",
photo: "",
description: "",
id: 0,
name: "",
rating: 0
}
];
const [movies, setMovies] = useState(initialValue);
useEffect(() => {
(async function() {
try {
//const response = await fetch(
//`http://192.168.1.164:5000/movies/display`
//);
//const json = await response.json();
//const result = json.data.result;
const result = [
{
category: …Run Code Online (Sandbox Code Playgroud) 我一直在使用React 16.7-alpha中的新钩子系统,当我正在处理的状态是一个对象或数组时,它会在useEffect中陷入无限循环.
首先,我使用useState并使用如下的空对象启动它:
const [obj, setObj] = useState({});
Run Code Online (Sandbox Code Playgroud)
然后,在useEffect中,我使用setObj将其再次设置为空对象.作为第二个参数,我传递[obj],希望如果对象的内容没有改变,它不会更新.但它不断更新.我想因为无论内容如何,这些都是不同的对象,让React认为它在不断变化?
useEffect(() => {
setIngredients({});
}, [ingredients]);
Run Code Online (Sandbox Code Playgroud)
数组也是如此,但作为一个原语,它不会像预期的那样卡在循环中.
使用这些新的钩子,在检查天气内容是否发生变化时,我应该如何处理对象和数组?
我正在使用 VSCode,当我将该行添加'react-hooks/exhaustive-deps': 'warn'到 .eslintrc.js 时,我在 ESLint 输出中得到以下内容:
Rules with suggestions must set the `meta.hasSuggestions` property to `true`. Occurred while linting
C:\Users\filepath.jsx:72 Rule: "react-hooks/exhaustive-deps"
Run Code Online (Sandbox Code Playgroud)
这会破坏所有其他 linting。我尝试将以下内容添加到我的 .eslintrc.js 中:
meta: {
hasSuggestions: true
},
Run Code Online (Sandbox Code Playgroud)
这给了我以下错误:
UnhandledPromiseRejectionWarning: Error: ESLint configuration in .eslintrc.js is invalid:
- Unexpected top-level property "meta".
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激。
这是我的 .eslintrc.js:
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: ['eslint:recommended', 'plugin:react/recommended', 'plugin:react-hooks/recommended'],
settings: {
'react': {
'version': 'detect'
}
},
parserOptions: {
ecmaFeatures: {
jsx: true,
}, …Run Code Online (Sandbox Code Playgroud) 从react官方文档我们知道“React依赖于Hooks的调用顺序”。那么,如果我想有条件地调用它,那么为钩子“保留”一个位置有什么问题吗?
function Component({flag, depA, depB}) {
if (flag) {
// just "reserving a spot"
useEffect(() => {}, [null, null])
} else {
useEffect(() => {
// ... actual hook
}, [depA, depB])
}
return <></>
}
Run Code Online (Sandbox Code Playgroud)
如果这有效,它也适用于吗useCallback?useLayoutEffect?useMemo?useImperativeHandle?
我已经测试了所有这些,并且在更复杂的上下文中,即使 linter 抱怨,它似乎也能工作。我错过了什么吗?
PS:如果像这样看起来有点没用,那是因为最终目标是让钩子的主要部分延迟加载import(),在导入被触发和解决之前,只需为钩子保留位置即可。
嗨,我一直被困在 React Function 中useState。我只是想学习 hooks 和 useState,但我什至费力寻找解决方案也没有任何进展。这是我的完整反应功能:
import React, { useState } from 'react';
import './MainPart.css';
function MainPart(props) {
const [orderData_, setOrderData_] = useState(props.orderData);
let topicData_ = props.topicData;
let titleData_ = props.titleData;
let infoData_ = props.infoData;
return (
<div className='MainPart'>
<div className='mainWindow'>{getPics(orderData_)}</div>
<div className='information'>
<div className='moreNewsDivs'>
<div className='moreNewsDiv1'>
<h4>MORE NEWS</h4>
</div>
<div className='moreNewsDiv2'>
<button
className='previous-round'
onClick={setOrderData_(previous(orderData_))}
>
‹
</button>
<button href='/#' className='next-round'>
›
</button>
</div>
</div>
<hr />
<div className='topicDiv'>
<h5 className='topicData'>{topicData_}</h5>
<h5 className='titleData'>{titleData_}</h5>
<h6 className='infoData'>{infoData_}</h6> …Run Code Online (Sandbox Code Playgroud) react-hooks ×10
reactjs ×10
javascript ×5
eslint ×1
eslintrc ×1
react-redux ×1
typescript ×1
websocket ×1