簡體   English   中英

在 reactstrap 中,如何從子組件自定義警報消息和可見 state?

[英]In reactstrap, how do I customize the alert message and visible state from a child component?

我正在使用 React 16.13.0 並嘗試使用 reactstrap Alert 組件在提交某些 forms 時顯示消息。 我已將 Alert 組件放置在我的 App 模板中我想要的位置...

import { Alert } from 'reactstrap';

function App() {
  return (
    <Router>
      <div className="App">
        <nav className="navbar navbar-expand-lg navbar-light fixed-top">
          <div className="container">
            <Link className="navbar-brand" to={"/add"}>
              Chicommons
            </Link>
            <NavBar />
          </div>
        </nav>

        <div className="auth-wrapper">
          <div className="auth-inner">
            <Alert color="info" isOpen={this.state.visible} >
              I am an alert and I will disappear in 2sec.!
            </Alert>
            <Switch>
              <Route exact path="/" component={Add} />
              <Route path="/add" component={Add} />
              <Route path="/edit/:id" component={Edit} />
              <Route path="/search" component={Search} />
              <Route path="/:coop_id/people" component={AddPerson} />
              <Route path="/:coop_id/listpeople" component={ListPeople} />
            </Switch>
          </div>
        </div>
      </div>
    </Router>
  );
}

export default App;

我在幾件事上遇到了麻煩。 我的表單組件之一,src/containers/FormContainer.jsx,有這個提交處理程序......

  const handleFormSubmit = (e) => {
    e.preventDefault();
    // Make a copy of the object in order to remove unneeded properties
    const NC = JSON.parse(JSON.stringify(coop));
    delete NC.addresses[0].country;

    const url = coop.id ? REACT_APP_PROXY + "/coops/" + coop.id : REACT_APP_PROXY + "/coops/";
    const method = coop.id ? "PATCH" : "POST";
    fetch(url, {
      method: method,
      body: JSON.stringify(NC),
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
    })
      .then((response) => {
        if (response.ok) {
          return response.json();
        } else {
          throw response;
        }
      })
      .then((data) => {
        const result = data;
        history.push({
          pathname: "/" + result.id + "/people",
          state: { coop: result },
        });
        window.scrollTo(0, 0);

        /** Would like to place alert here **/

      })
      .catch((err) => {
        console.log(err);
        err.text().then((errorMessage) => {
          setErrors(JSON.parse(errorMessage));
        });
      });
  };

我想使用上述處理程序中生成的自定義消息啟用 reactstrap 警報。 但是,我不知道如何控制父組件的state。 我假設我必須在父組件中創建一些消息 state 並控制我已經擁有的可見 state,但不確定如何從孩子那里做到這一點。

就在function App() { . 添加:

const [alertMessage, setAlertMessage] = React.useState("")

並將您的警報更改為:

<Alert color="info" isOpen={alertMessage!=""} toggle={()=>setAlertMessage("")} >
    {alertMessage}
</Alert>

然后我不知道您的應用程序的 rest 是如何布局的,但是您想將setAlertMessage handleFormSubmit作為回調傳遞給 handleFormSubmit,並在setErrors中/附近調用它

您可以創建一個上下文,以便在應用程序的任何位置輕松訪問警報。

AlertProvider.js

import React, { useState, useCallback, useContext, createContext } from 'react'

const AlertContext = createContext()

export function AlertProvider(props) {
  const [open, setOpen] = useState(false)
  const [message, setMessage] = useState()


  const handleClose = useCallback(() => {
    setOpen(false)
  }, [setOpen])

  const handleOpen = useCallback(message => {
    setMessage(message)
    setOpen(true)
  }, [setMessage, setOpen])
    
  return (
    <AlertContext.Provider value={[handleOpen, handleClose]}>
      {props.children}
      <Alert color="info" isOpen={open} toggle={handleClose} >
        {message}
      </Alert>
    </AlertContext.Provider>
  )
}


export function useAlert() {
  const context = useContext(AlertContext);
  if (!context)
    throw new Error('`useAlert()` must be called inside an `AlertProvider` child.')

  return context
}

更新您的App.js

import { Alert } from 'reactstrap';
import { AlertProvider } from './AlertProvider';

function App() {
  return (
    <AlertProvider>
      <Router>
        <div className="App">
          <nav className="navbar navbar-expand-lg navbar-light fixed-top">
            <div className="container">
              <Link className="navbar-brand" to={"/add"}>
                Chicommons
              </Link>
              <NavBar />
            </div>
          </nav>

          <div className="auth-wrapper">
            <div className="auth-inner">
              <Switch>
                <Route exact path="/" component={Add} />
                <Route path="/add" component={Add} />
                <Route path="/edit/:id" component={Edit} />
                <Route path="/search" component={Search} />
                <Route path="/:coop_id/people" component={AddPerson} />
                <Route path="/:coop_id/listpeople" component={ListPeople} />
              </Switch>
            </div>
          </div>
        </div>
      </Router>
    </AlertProvider>
  );
}

export default App;

然后,您可以在功能組件中使用它:

import React, { useEffect } from 'react'
import { useAlert } from './AlertProvider'

function MyComponent() {
  const [open, close] = useAlert();

  useEffect(() => {
    // when some condition is met
      open("Hi") // closable with the toggle, or in code via close()
  })
}

這通過調用open()close()使用命令式打開和關閉。 如果你想要一種聲明式的情緒,上下文應該直接返回setMessagesetOpen函數。

您還可以嘗試將警報組件放置在其他地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM