如何使用 useEffect 中的异步 return 值作为 useState 中的默认值?
How use async return value from useEffect as default value in useState?
我创建了一个简单的示例 https://codesandbox.io/s/4zq852m7j0。
如您所见,我正在从远程源获取一些数据。我想使用 return 值作为我的文本字段中的值。
const useFetch = () => {
const [value, setValue] = useState("");
useEffect(
async () => {
const response = await fetch("https://httpbin.org/get?foo=bar");
const data = await response.json();
setValue(data.args.foo);
},
[value]
);
return value;
};
然而,使用 useState
函数中的值不起作用。我认为 useState
仅在第一次渲染时使用默认值。第一次渲染时,显然没有设置值,因为它是异步的。文本字段应具有值 bar
但它是空的。
function App() {
const remoteName = useFetch();
// i want to see the remote value inside my textfield
const [name, setName] = useState(remoteName);
const onChange = event => {
setName(event.target.value);
};
return (
<div className="App">
<p>remote name: {remoteName}</p>
<p>local name: {name}</p>
<input onChange={onChange} value={name} />
</div>
);
}
从远程获取值后,我希望能够在本地更改它。
有什么想法吗?
这与在 class 组件中异步设置初始状态完全相同:
state = {};
async componentDidMount() {
const response = await fetch(...);
...
this.setState(...);
}
异步检索的状态在初始渲染期间不可用。功能组件应该使用与 class 组件相同的技术,即有条件地渲染依赖于状态的子组件:
return name && <div className="App">...</div>;
这样 useFetch
就没有理由拥有自己的状态,它可以与组件(example)保持共同状态:
const useFetch = () => {
const [value, setValue] = useState("");
useEffect(
async () => {
const response = await fetch("https://httpbin.org/get?foo=bar");
const data = await response.json();
setValue(data.args.foo);
},
[] // executed on component mount
);
return [value, setValue];
};
function App() {
const [name, setName] = useFetch();
const onChange = event => {
setName(event.target.value);
};
return name && (
<div className="App">
<p>local name: {name}</p>
<input onChange={onChange} value={name} />
</div>
);
}
现在 useFetch
returns 一个异步可用的值,您需要的是在 remoteValue 可用时更新 localState,为此您可以编写一个 effect
const remoteName = useFetch();
// i want to see the remote value inside my textfield
const [name, setName] = useState(remoteName);
useEffect(
() => {
console.log("inside effect");
setName(remoteName);
},
[remoteName] // run when remoteName changes
);
const onChange = event => {
setName(event.target.value);
};
是否不能将初始状态作为异步函数传递?
即
const [value, setValue] = useState(async () => fetch("https://httpbin.org/get?foo=bar").json().args.foo);
我创建了一个简单的示例 https://codesandbox.io/s/4zq852m7j0。
如您所见,我正在从远程源获取一些数据。我想使用 return 值作为我的文本字段中的值。
const useFetch = () => {
const [value, setValue] = useState("");
useEffect(
async () => {
const response = await fetch("https://httpbin.org/get?foo=bar");
const data = await response.json();
setValue(data.args.foo);
},
[value]
);
return value;
};
然而,使用 useState
函数中的值不起作用。我认为 useState
仅在第一次渲染时使用默认值。第一次渲染时,显然没有设置值,因为它是异步的。文本字段应具有值 bar
但它是空的。
function App() {
const remoteName = useFetch();
// i want to see the remote value inside my textfield
const [name, setName] = useState(remoteName);
const onChange = event => {
setName(event.target.value);
};
return (
<div className="App">
<p>remote name: {remoteName}</p>
<p>local name: {name}</p>
<input onChange={onChange} value={name} />
</div>
);
}
从远程获取值后,我希望能够在本地更改它。
有什么想法吗?
这与在 class 组件中异步设置初始状态完全相同:
state = {};
async componentDidMount() {
const response = await fetch(...);
...
this.setState(...);
}
异步检索的状态在初始渲染期间不可用。功能组件应该使用与 class 组件相同的技术,即有条件地渲染依赖于状态的子组件:
return name && <div className="App">...</div>;
这样 useFetch
就没有理由拥有自己的状态,它可以与组件(example)保持共同状态:
const useFetch = () => {
const [value, setValue] = useState("");
useEffect(
async () => {
const response = await fetch("https://httpbin.org/get?foo=bar");
const data = await response.json();
setValue(data.args.foo);
},
[] // executed on component mount
);
return [value, setValue];
};
function App() {
const [name, setName] = useFetch();
const onChange = event => {
setName(event.target.value);
};
return name && (
<div className="App">
<p>local name: {name}</p>
<input onChange={onChange} value={name} />
</div>
);
}
现在 useFetch
returns 一个异步可用的值,您需要的是在 remoteValue 可用时更新 localState,为此您可以编写一个 effect
const remoteName = useFetch();
// i want to see the remote value inside my textfield
const [name, setName] = useState(remoteName);
useEffect(
() => {
console.log("inside effect");
setName(remoteName);
},
[remoteName] // run when remoteName changes
);
const onChange = event => {
setName(event.target.value);
};
是否不能将初始状态作为异步函数传递?
即
const [value, setValue] = useState(async () => fetch("https://httpbin.org/get?foo=bar").json().args.foo);