React-如何从子功能组件执行功能

时间:2019-04-23 07:16:38

标签: reactjs

我需要您的组件帮助,我需要在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])

1 个答案:

答案 0 :(得分:0)

在子功能组件中,您可以传递由功能组成的props对象。在该函数中,将您的子功能组件状态传递到那里,并在父组件中设置那里的状态,并在渲染时将新状态传递回功能组件。

父类:-

parentFunction = () => {
   //set your state here
}
render() {
   return(
     <DarkSky auth={xyz} parentFunction={this.parentFunction} {...this.state}/>
   )
}

子功能组件:-

const DarkSky = ({auth, parentFunction, state}) => {
}

正如您一直在使用react挂钩一样,它具有隔离状态的功能。因此,您可以做的是制作一个可重用的组件(自定义钩子):-

//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>

}