簡體   English   中英

使用從一個組件到另一個組件的異步函數

[英]Use an async function from one component to another

我正在用松露的反應盒編寫 Dapp。 對於該應用程序,我需要在App.js另一個組件中使用我的智能合約中的一個函數(只有兩個 getter)。 這個函數是getUser ,它需要來自Login.js

應用程序.js:

class App extends Component {
  state = {
    web3: null,
    contract: undefined,
    account: null,
    user: {
      id: null,
      name: '',
      password: ''
    }
  };

  componentDidMount = async () => {
    try {
      const web3 = await getWeb3();
      const accounts = await web3.eth.getAccounts();
      const networkId = await web3.eth.net.getId();
      const deployedNetwork = Login.networks[networkId];
      const instance = new web3.eth.Contract(
        Login.abi,
        deployedNetwork && deployedNetwork.address,
      );
      this.setState({ web3, accounts, contract: instance });
    } catch (error) {
      alert(
        `Failed to load web3, accounts, or contract.       
         Check console for details.`,
      );
      console.error(error);
    }
  };

  getUser = async (event) => {
    const userID = this.state.id;
    const userName = await this.state.contract.methods 
                     .getUsername(userID).call();
    const userPassword = await this.state.contract.methods 
                        .getPassword(userID).call();
    console.log(userName + ' - ' +userPassword);
  };

  render() {
    if (!this.state.web3) {
      return <div>Loading Web3, accounts, and contract...</div>;
    }
    return (
      <div className="App">
      </div>
    );
  }
}

export default App;

登錄.js:

class App extends Component{

  handleInputChange = (event) => {
    let input = event.target;
    let name = event.target.name;
    let value = input.value;
    this.setState({
      [name]: value
    })
  }
render() {
    return (
      <div className='Login'>
        <form>
          <label>
            <span>Barcode:</span>
            <input name="id" type="number" required    
                   onChange={this.handleInputChange} />
          </label>
          <button type="submit" value="submit">Get user data</button>
        </form>
      </div>
    );
  }
}

export default Login;

我首先嘗試導出getUser函數:

應用程序.js:

 export const getUser = async (event) => { const userID = this.state.id; const userName = await this.state.contract.methods .getUsername(userID).call(); const userPassword = await this.state.contract.methods .getPassword(userID).call(); console.log(userName + ' - ' +userPassword); };

登錄.js:

 import {getUser} from ...

但我收到以下錯誤:

 Unhandled Rejection (TypeError): Cannot read property 'state' of undefined

然后我嘗試在Login添加相同的componentDidMount和在App.js找到的state (帶有導入),但是我收到以下錯誤:

 TypeError: Cannot read property 'methods' of null

我不再知道該怎么做。 所以我想請教一些幫助。

我預先感謝任何願意花時間幫助我的人。

您只需要在組件之間傳遞值。 假設 onClick 您將從登錄移動到應用程序組件,並且您將傳遞 id 和名稱。

onClick=(id,name)=>{
  history.push({
           pathname: '/secondpage', //app component url
           state: { id: id, name: name }
       })
}

歷史記錄可以從 react-router 導入

然后在應用程序組件中,您可以在this.props.location.state訪問此值

如果要通過組件發送值,請在登錄組件中像這樣聲明 app 組件,

<App 
  id={id}
  name={name}
/> 

然后在 app 組件中你可以得到this.props的值

全局狀態管理

您正在尋找一種在全局級別管理狀態的方法。 對於這個問題,有很多解決方案存在並被廣泛使用。

解決方案1:道具或“道具鑽孔”

這個想法是將狀態傳遞給需要它的每個組件。 只有在傳遞非全局級別的 props 或只有少數組件樹需要的 props 時,才應該考慮這樣做。

傳遞道具的一個例子是在官方文檔( https://reactjs.org/docs/context.html

解決方案 2:反應上下文 API

React 內部已經有一個被廣泛使用的內置功能,稱為 Context API 來解決這個問題。 使用示例也在文檔中。 https://reactjs.org/docs/context.html

Context 提供了一種通過組件樹傳遞數據的方法,而無需在每個級別手動向下傳遞 props。

TLDR; 如果您需要讓您的狀態處於全局級別,其中許多組件樹需要訪問它,這可能是解決方案。

暫無
暫無

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

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