我想創建一個可以更新匯入的嵌套組態檔的應用程式(類似于 swagger)。
我創建了一個 json 組態檔,并在https://transform.tools/json-to-typescript的幫助下為其生成了介面
然后我匯入原始的 json 組態檔,將其轉換為嵌套介面并將其傳遞給useState鉤子。問題是,我如何從應用程式更新單個值?
介面.ts
export interface Config {
project_info: ProjectInfo
modules: Module[]
}
export interface ProjectInfo {
go_version: number
name: string
port: number
}
主頁.tsx
import React, { useState, useReducer } from "react"
import { Module, Endpoint, UrlParam, Body, Config, ProjectInfo } from "../interfaces"
import Header from "./Header"
import json_config from "../../../config.json"
export const Homepage = () => {
// used to filter the selected module
const [currentlySelectedModule, setCurrentlySelectedModule] = useState("")
// import json file and convert it to the nested interface
const placeholder_config: Config = JSON.parse(JSON.stringify(json_config))
// convert the imported json config to hook, that has the form of generated interface
const [config, setConfig] = useState<Config>(placeholder_config)
return (
<div className="code py-14 grid gap-14 mb-30">
<div>
<div className="fs-7 fw-700">ProjectInfo</div>
<div className="">
<div>project_name :{config.project_info.name}</div>
<div>
project_name:
<input
className="module__endpoint_value_input endpoint__input_url"
value={config.project_info.name}
type="text"
// onChange={(e) => setConfig((e) => (config.project_info.name = e.target.value))}
// onChange={(e) => setPlaceholderConfig(() => config.project_info.name = e.target.value)}
/>
</div>
<div>go_version :{config.project_info.go_version}</div>
<div>port :{config.project_info.port}</div>
</div>
</div>
</div>
)
}
所以我正在發送整個組態檔,但想更改嵌套介面值。
在這種情況下我該如何更新ProjectInfo.name?此外,useState這種情況下最好的鉤子是什么?
幫助表示贊賞。
uj5u.com熱心網友回復:
您的代碼中有兩個相當大的錯誤:
- 傳遞給
setConfig的回呼不回傳新配置 - 狀態在此回呼中發生變化
您可以像這樣為您的配置實作自定義掛鉤:
import { useState } from 'react';
function useConfig(props) {
const [config, setConfig] = useState(props.config);
// Setter for config.project_info.name
// for other properties there should be other setters
const setProjectName = (name) => {
setConfig((config) => {
// Should copy every level of data structure manually
...config,
project_info: {
...config.project_info,
name
}
})
}
return {
config,
setProjectName
}
}
然后在您的組件中使用它:
import json_config from "../../../config.json"
const Homepage = () => {
const { config, setProjectName } = useConfig({ config: json_config });
const handleNameChange = (event) => {
setProjectName(event.currentTarget.value)
}
return (
<input
type="text"
value={config.project_info.name}
onChange={handleNameChange}
/>
)
}
If you don't want to copy deep nested objects manually, you could use libraries like Immer, which allows you to write "mutating" code, but not actually mutate it. Other option is to use reactive state management library like MobX.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/438180.html
