gpt4 book ai didi

react-hooks - useState 取决于其他状态

转载 作者:行者123 更新时间:2023-12-04 15:38:12 24 4
gpt4 key购买 nike

我有这个 useSiren Hook ,它应该使用传入的 json 参数更新其状态,但它没有。

在第一次调用时,json 是一个空对象,因为 fetch 效果还没有运行。在第二次调用时,它也是一个空对象(由 loadingApp 中设置为 true 触发)在第三次调用时,它充满了有效数据。但是,未应用有效数据。状态保持其初始值。

我猜想必须以某种方式调用 setSiren 来更新它,因为初始状态只能设置一次。但我该怎么做呢?谁应该调用 `setSiren?

import { h, render } from 'https://unpkg.com/preact@latest?module';
import { useEffect, useState, useCallback } from 'https://unpkg.com/preact@latest/hooks/dist/hooks.module.js?module';
import htm from "https://unpkg.com/htm@latest/dist/htm.module.js?module";

const html = htm.bind(h);

function useFetch({
method = "GET",
autoFetch = true,
href,
body
}) {
const [loading, setLoading] = useState(false)
const [error, setError] = useState()
const [response, setResponse] = useState()
const [isCancelled, cancel] = useState()
const [json, setJson] = useState({})

const sendRequest = async payload => {
try {
setLoading(true)
setError(undefined)
const response = await fetch(href.replace("http://", "https://"), {
method
})
const json = await response.json()
if (!isCancelled) {
setJson(json)
setResponse(response)
}
return json
} catch (err) {
if (!isCancelled) {
setError(err)
}
throw err
} finally {
setLoading(false)
}
}

if (autoFetch) {
useEffect(() => {
sendRequest(body)
return () => cancel(true)
}, [])
}

return [{
loading,
response,
error,
json
},
sendRequest
]
}

function useSiren(json) {
const [{ entities = [], actions = [], links, title }, setSiren] = useState(json)
const state = (entities.find(entity => entity.class === "state")) || {}
return [
{
title,
state,
actions
},
setSiren
]
}

function Action(props) {
const [{ loading, error, json }, sendRequest] = useFetch({ autoFetch: false, href: props.href, method: props.method })
const requestAndUpdate = () => {
sendRequest().then(props.onRefresh)
}
return (
html`
<button disabled=${loading} onClick=${requestAndUpdate}>
${props.title}
</button>
`
)
}

function App() {
const [{ loading, json }, sendRequest] = useFetch({ href: "https://restlr.io/toggle/0" })
const [{ state, actions }, setSiren] = useSiren(json)
return (
html`<div>
<div>State: ${loading ? "Loading..." : (state.properties && state.properties.value)}</div>
${actions.map(action => html`<${Action} href=${action.href} title=${action.title || action.name} method=${action.method} onRefresh=${setSiren}/>`)}
<button disabled=${loading} onClick=${sendRequest}>
REFRESH
</button>
</div>
`
);
}
render(html`<${App}/>`, document.body)

最佳答案

也许您想做的是在 json 参数更改时更新 siren 状态?您可以使用 useEffect 自动更新它。

function useSiren(json) {
const [{ entities = [], actions = [], links, title }, setSiren] = useState(json)

useEffect(() => { // here
setSiren(json)
}, [json])

const state = (entities.find(entity => entity.class === "state")) || {}
return [
{
title,
state,
actions
},
setSiren
]
}

关于react-hooks - useState 取决于其他状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59042924/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com