React Context API / 在上下文文件中绑定函数?

React Context API / Bind function in context file?

我正在尝试使用上下文 api。我在提交表单时收到错误 TypeError: 'this.props.fetchWeather is not a function' 。

我的 WeatherContext 文件有一个 WeatherProvider 和 WeatherConsumer。我的状态和一个 fetchWeather 函数就是这个文件。当我记录传递给值的内容时,fetchWeather 记录为未定义。

{term: "", forecast: Array(0), fetchWeather: undefined}

我的问题是如何在 WeatherContext 中定义 fetchWeather 函数?我试着绑定它。我不确定我哪里出错了。

此问题已更新以反映我所做的更改...

src/index.js

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

import { WeatherProvider, WeatherContext } from 
'./context/WeatherContext'

ReactDOM.render(
     <WeatherProvider>
        <WeatherContext.Consumer>
            {({ term, forecast, fetchWeather }) => 
                 <App term={ term } 
                      forecast={ forecast } 
                      fetchWeather={ fetchWeather }  />
            }
        </WeatherContext.Consumer>
     </WeatherProvider>, 
     document.getElementById('root')
);
registerServiceWorker();

src/app.js

import React, { Component } from 'react'
import SearchForm from './components/Search/Search_Form'

export default class App extends React.Component {
    render() {
        return (
          <div className="App">
            <SearchForm {...this.props}/>
          </div>
        );
    }
}

src/context/WeatherContext

import React, { Component } from 'react'
import axios from 'axios'
import _ from 'lodash'

export const WeatherContext = React.createContext();

export class WeatherProvider extends React.Component {

    state = {
        context: {
            input: '',
            forecast: [],
            fetchWeather: this.fetchWeather
        }
    }

     fetchWeather = (term) => {
        let QUERY = term
        const KEY = `key`
        let URL = `http://url.com/q=${QUERY}&appid=${KEY}`

        axios.get(URL)
        .then( res => {
          // do something ...
        })
    }

    render() {
        return (
            <WeatherContext.Provider 
            value={{ ...this.state.context }} >
                { this.props.children }
            </WeatherContext.Provider>
        )
    }
}

src/components/Search/index

import React from 'react'
import { WeatherContext } from '../../context/WeatherContext'
import SearchForm from './Search_Form'

export default (props) => (
    <WeatherContext.Consumer>
        {
            ({fetchWeather}) => 
            <SearchForm {...props} fetchWeather={fetchWeather} />
        }
    </WeatherContext.Consumer>
)

src/components/Search/Search_Form

import React, { Component } from 'react'

class SearchForm extends Component {
    handleFormSubmit = (e) => {
        e.preventDefault();
        let term = this.input.value
        this.props.fetchWeather(term)
    }

    handleClear =(e) => {
        e.preventDefault();
        this.setState({
            input: ''
        }) 
    }

    render() {
        console.log(this.props);
        return (
         <div>
             <form className="form" onSubmit={ this.handleFormSubmit }>
                <input type='text'
                    placeholder='Enter a US City'
                    ref={input => { this.input = input }}/>
                <button type="submit"> Search </button>        
                <button onClick={ this.handleClear }> x </button>
             </form>
         </div>

        )
     }
}


 export default SearchForm;

从 App 组件,您没有将 props 传递给 SearchForm 组件,因为您在 components/Search/index.js 中用 With WeatherContext 包装了 SearchForm,而您在 [=21] 中没有使用=],fetchWeather 属性 SearchForm 未定义。您需要在 App.js 中使用 SearchForm from components/Search/index.js like

import React, { Component } from 'react'
import SearchForm from './components/Search/index.js'

export default class App extends React.Component {
    render() {
        return (
          <div className="App">
            <SearchForm />
          </div>
        );
    }
}

从App.js

传递道具
import React, { Component } from 'react'
import SearchForm from './components/Search/Search_Form'

export default class App extends React.Component {
    render() {
        return (
          <div className="App">
            <SearchForm {...this.props}/>
          </div>
        );
    }
}

解决了未定义的 fetchWeather 问题。答案是将 fetchWeather 函数从状态中取出,并将其放入 WeatherProvider class 的构造函数中。然后绑定它。我累了...