reactjs - React - 如何从子功能组件执行功能
问题描述
我需要你的帮助,我需要在 React 中重用一个组件。现在我有一个设置页面,人们可以在其中配置与其他应用程序的一些连接。不同的应用程序设置看起来有些相同,但并不完全一样。当然我可以用道具来解决这个问题,但buttonClick
代码也不同,我不知道怎么做。以下是 1 个设置的示例:
const DarkSky = ({auth}) => {
const [config, setConfig] = useState(getLocalStorage('darksky') || {api_key: '', success: false});
const saveConfig = async () => {
const data = await makeAPICall('/api/darksky/current', 'GET', null, await auth.getAccessToken())
setConfig({api_key: config.api_key, success: true})
}
useEffect(() => {
setLocalStorage('darksky', config)
}, [config])
const configHandler = (event) => setConfig({...config, 'api_key': event.target.value});
const buttonClickHandler = (event) => saveConfig()
let formItems = [{
name: 'apikey',
type: 'input',
label: 'API key',
value: config.api_key,
changehandler: configHandler
}]
return <div><h2>DarkSky connection</h2>
<DefaultFormRow data={formItems} buttons={[{id: 'saveapikey', click: buttonClickHandler, buttonclass: (config.success ? 'success' : 'danger'), disabled: false, text: 'Sla API key op'}]} />
<p>Config correct: {config.success === true ? 'Ja' : 'Nee'} </p>
</div>
}
在这个(工作)示例中,有受控输入(formItems)使用以下代码更新配置状态
const configHandler = (event) => setConfig({...config, 'api_key': event.target.value});
:我可以通过执行以下操作使其可重用:
const configHandler = (event) => setConfig({...config, [event.target.name]: event.target.value});
然后有一个 buttonClick 处理程序,在人们单击保存按钮后触发。在这种情况下它会触发saveConfig()
,但在其他情况下,它需要做其他事情。如果我从父组件(设置页面)传递它,这个函数将从父组件执行,我无法访问这个子组件的状态。
你们应该怎么做呢?我不认为我可以在子类中执行函数吗?而且我不想在父类中添加所有这些不同的状态,因为我喜欢这种干净的外观(状态在它自己的组件中)。
不知道我有没有说清楚,如果你们问,我会添加更多细节。
编辑:此时我有这个:
const APIManagement = ({auth}) => {
return <div>
<SolarEdge />
<Tado />
<DarkSky />
<Enelogic />
</div>
}
这里的不同组件看起来很像,所以如果我能有这样的东西会很好:
const APIManagement = ({auth}) => {
const saveFunction1 = () => {how to save tado settings here}
const saveFunction2 = () => {how to save enelogic settings here}
const saveFunction3 = () => {how to save darksky settings here}
const saveFunction4 = () => {how to save solaredge settings here}
return <div>
<APISetting title='Tado' saveFunction={saveFunction1}/>
<APISetting title='Enelogic' saveFunction={saveFunction2}/>
<APISetting title='DarkSky' saveFunction={saveFunction3}/>
<APISetting title='SolarEdge' saveFunction={saveFunction4}/>
</div>
}
EDIT2:通过保存功能将设置从浏览器添加到 localStorage 来保持设置:
useEffect(() => {
setLocalStorage('darksky', config)
}, [config])
解决方案
在子功能组件中,您可以传递由功能组成的道具对象。在该函数中,将您的子功能组件状态传递到那里并在父组件中设置状态,当它呈现时,它将新状态传递回功能组件。
父类:-
parentFunction = () => {
//set your state here
}
render() {
return(
<DarkSky auth={xyz} parentFunction={this.parentFunction} {...this.state}/>
)
}
子功能组件:-
const DarkSky = ({auth, parentFunction, state}) => {
}
正如您一直在使用反应钩子一样,它具有隔离状态的功能。所以你可以做的是制作一个可重用的组件(自定义钩子): -
//put this is another js file
export function useConfig(key, defaultConfig) {
const [config, setConfig] = useState(getLocalStorage(key) ||
defaultConfig);
useEffect(() => {
setLocalStorage(key, config)
}, [config])
return config;
}
import { useConfig } from '/js/file/path'
const APISetting = ({title, saveFunction}) => {
let config = useConfig(title, {api_key: '', success: false})
const saveConfig = async () => {
const data = await makeAPICall(`/api/${title}/current`, 'GET', null, await auth.getAccessToken())
// setConfig({api_key: config.api_key, success: true})
const newConfig = useConfig({api_key: config.api_key, success: true})
saveFunction(newConfig);
}
const configHandler = (event) => { config = useConfig({...config, 'api_key': event.target.value}) };
const buttonClickHandler = (event) => saveConfig()
let formItems = [{
name: 'apikey',
type: 'input',
label: 'API key',
value: config.api_key,
changehandler: configHandler
}]
return <div><h2>{title} connection</h2>
<DefaultFormRow data={formItems} buttons={[{id: 'saveapikey', click: buttonClickHandler, buttonclass: (config.success ? 'success' : 'danger'), disabled: false, text: 'Sla API key op'}]} />
<p>Config correct: {config.success === true ? 'Ja' : 'Nee'} </p>
</div>
}
In your parent component you will get like this :-
const APIManagement = ({auth}) => {
const saveFunction1 = (config) => {console.log('the config is', config)}
const saveFunction2 = () => {how to save enelogic settings here}
const saveFunction3 = () => {how to save darksky settings here}
const saveFunction4 = () => {how to save solaredge settings here}
return <div>
<APISetting title='Tado' saveFunction={saveFunction1}/>
<APISetting title='Enelogic' saveFunction={saveFunction2}/>
<APISetting title='DarkSky' saveFunction={saveFunction3}/>
<APISetting title='SolarEdge' saveFunction={saveFunction4}/>
</div>
}
推荐阅读
- php - laravel 如何与 Ajax 一起工作?
- odoo-9 - odoo ir.actions.server id 未找到
- java - PSQLException: Can't infer the SQL type ... 使用 setObject() (我正在使用它!)
- android - 在这个例子中,我可以在 Textview2 上放置 TextView1 吗?
- regex - 拆分一个字符串,只取 5 个项目。但将字符限制为 <20
- python - Mysql表格列变成按钮,可以吗?
- azure - 如何指定 BlobTrigger 绑定以使容器名称可配置?
- arrays - Laravel 为数字字段返回一个空数组
- linux - 使用 sed 在 Bash 中解析 HTML 表格
- vue.js - Vuetify 断点在 Nuxt.js 中不起作用