我正试图将我的头包裹在自定义钩子上。我理解普通钩子很好,但我的问题是,在编写自定义钩子时,它与普通函数有什么区别?我的意思是为什么不称其为普通函数而不是将其称为 use*
假设我有一些依赖于其他状态的状态(例如当A改变时我希望B改变).
是否适合创建一个观察A并在useEffect钩子中设置B的钩子?
效果是否级联,当我点击按钮时,第一个效果会激发,导致b改变,导致第二个效果在下一个渲染之前触发?构造这样的代码有任何性能缺点吗?
let MyComponent = props => {
let [a, setA] = useState(1)
let [b, setB] = useState(2)
useEffect(
() => {
if (/*some stuff is true*/) {
setB(3)
}
},
[a],
)
useEffect(
() => {
// do some stuff
},
[b],
)
return (
<button
onClick={() => {
setA(5)
}}
>
click me
</button>
)
}
Run Code Online (Sandbox Code Playgroud) 我有一个简单的组件,它在我的 React 应用程序中充当错误边界,并将任何错误传递给日志记录服务。
它看起来像这样:
export class CatchError extends React.PureComponent {
state = {
hasError: false
}
componentDidCatch(error, info) {
this.props.log({ error, info })
this.setState({ hasError: true })
}
render() {
const child = typeof this.props.children === "function"
? this.props.children({ error: hasError })
: children
return React.cloneElement(child, { error: this.state.hasError })
}
}
Run Code Online (Sandbox Code Playgroud)
是否有一个 React 钩子相当于componentDidCatch这样我可以使这个组件成为一个函数而不是一个类?
所以它可能看起来像这样:
export function CatchError({ children, log }) {
const [hasError, setHasError] = useState(false)
const caught = useDidCatch()
useEffect(() => {
const [error, info] …Run Code Online (Sandbox Code Playgroud) 在创建 React 应用程序时,如果我使用 hook useSelector,我需要遵守 hooks 调用规则(只能从功能组件的顶层调用它)。如果我使用mapStateToProps,我会在道具中获得状态,我可以在任何地方使用它而没有任何问题......同样的问题useDispatch
与使用钩子相比,除了节省代码行之外,使用钩子还有什么好处mapStateToProps?
随着React 中钩子的引入,现在的主要困惑是何时使用带钩子和类组件的功能组件,因为在钩子的帮助下state,lifecycle hooks即使在功能组件中也可以获得和部分.所以,我有以下问题
例如,带有钩子的功能组件无法像类组件那样帮助执行.他们无法跳过重新渲染,因为他们没有shouldComponentUpdate实现.还有原因吗?
提前致谢.
我正在尝试使用新的react useReducer API来获取一些数据,并停留在需要异步获取的阶段。我只是不知道如何:/
如何将数据获取放置在switch语句中,或者这不是应该完成的方式?
import React from 'react'
const ProfileContext = React.createContext()
const initialState = {
data: false
}
let reducer = async (state, action) => {
switch (action.type) {
case 'unload':
return initialState
case 'reload':
return { data: reloadProfile() } //how to do it???
}
}
const reloadProfile = async () => {
try {
let profileData = await fetch('/profile')
profileData = await profileData.json()
return profileData
} catch (error) {
console.log(error)
}
}
function ProfileContextProvider(props) {
let [profile, profileR] …Run Code Online (Sandbox Code Playgroud) 根据文件:
componentDidUpdate()更新发生后立即调用.初始渲染不会调用此方法.
我们可以使用新的useEffect()钩子来模拟componentDidUpdate(),但似乎useEffect()是在每次渲染之后运行,甚至是第一次.如何让它不能在初始渲染上运行?
正如您在下面的示例中所看到的,componentDidUpdateFunction在初始渲染期间打印,但componentDidUpdateClass在初始渲染期间未打印.
function ComponentDidUpdateFunction() {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
console.log("componentDidUpdateFunction");
});
return (
<div>
<p>componentDidUpdateFunction: {count} times</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
Click Me
</button>
</div>
);
}
class ComponentDidUpdateClass extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
componentDidUpdate() {
console.log("componentDidUpdateClass");
}
render() {
return (
<div>
<p>componentDidUpdateClass: {this.state.count} times</p>
<button
onClick={() => { …Run Code Online (Sandbox Code Playgroud)让我解释一下此代码的结果,以便轻松地询问我的问题。
const ForExample = () => {
const [name, setName] = useState('');
const [username, setUsername] = useState('');
useEffect(() => {
console.log('effect');
console.log({
name,
username
});
return () => {
console.log('cleaned up');
console.log({
name,
username
});
};
}, [username]);
const handleName = e => {
const { value } = e.target;
setName(value);
};
const handleUsername = e => {
const { value } = e.target;
setUsername(value);
};
return (
<div>
<div>
<input value={name} onChange={handleName} />
<input value={username} onChange={handleUsername} />
</div>
<div> …Run Code Online (Sandbox Code Playgroud) 以下 onClick 回调函数将导致 1 次重新渲染:
const handleClickSync = () => {
// Order of setters doesn't matter - React lumps all state changes together
// The result is one single re-rendering
setValue("two");
setIsCondition(true);
setNumber(2);
};
Run Code Online (Sandbox Code Playgroud)
React 将所有三个状态更改集中在一起并导致 1 次重新渲染。
然而,以下 onClick 回调函数将导致 3 次重新渲染:
const handleClickAsync = () => {
setTimeout(() => {
// Inside of an async function (here: setTimeout) the order of setter functions matters.
setValue("two");
setIsCondition(true);
setNumber(2);
});
};
Run Code Online (Sandbox Code Playgroud)
这对每个设置者来说都是一次重新渲染useState。此外,设置器的顺序会影响每个渲染中的值。
问题:为什么我使函数异步(此处为 via setTimeout)这一事实会导致状态更改相继发生,从而导致 …
问题出在这里:我试图在单击按钮时调用2个函数。这两个函数都会更新状态(我正在使用useState挂钩)。第一个函数将value1正确更新为'new 1',但是在1s(setTimeout)之后触发,第二个函数将值2更改为'new 2',但是!它将value1设置回'1'。为什么会这样呢?提前致谢!
import React, { useState } from "react";
const Test = () => {
const [state, setState] = useState({
value1: "1",
value2: "2"
});
const changeValue1 = () => {
setState({ ...state, value1: "new 1" });
};
const changeValue2 = () => {
setState({ ...state, value2: "new 2" });
};
return (
<>
<button
onClick={() => {
changeValue1();
setTimeout(changeValue2, 1000);
}}
>
CHANGE BOTH
</button>
<h1>{state.value1}</h1>
<h1>{state.value2}</h1>
</>
);
};
export default Test;
Run Code Online (Sandbox Code Playgroud)