我想要创建一个应用程序,可以更新导入的嵌套配置文件(类似于swagger)。
我创建了一个json配置文件,并在https://transform.tools/json-to-typescript的帮助下为它生成了接口。
然后导入原始的json文件,将其转换为嵌套接口,并将其传递给useState钩子。问题是,如何从应用程序中更新单个值?
interfaces.ts
export interface Config {
project_info: ProjectInfo
modules: Module[]
}
export interface ProjectInfo {
go_version: number
name: string
port: number
}Homepage.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是最好的钩吗?
帮助感激。
发布于 2022-03-05 21:58:15
代码中有两个相当大的错误:
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}
/>
)
}如果您不想手动复制深度嵌套的对象,可以使用像二聚体这样的库,它允许您编写“变异”代码,而不是实际地修改它。其他选项是使用像MobX这样的反应性状态管理库。
https://stackoverflow.com/questions/71362509
复制相似问题