从一个类导入一个回调到打字稿中的另一个回调

时间:2019-03-17 12:03:37

标签: reactjs typescript

我正在使用打字稿3。

我有这个地图组件:

import * as React from 'react';
import GoogleMapReact from 'google-map-react';
import { any } from 'prop-types';
import {Coords} from 'google-map-react';
export interface HelloProps { center: Coords ; zoom: number ; }


const AnyReactComponent = ( {text} : { lat: any,text:any,lng:any}) => <div>{text}</div>;
export class SimpleMap extends React.Component <HelloProps, {}> {
  defaultProps = {
    center: {
      lat: 59.95,
      lng: 30.33
    },
    zoom: 11
  };
  myCallbackMap = (dataFromChild:number) => {
    this.defaultProps.zoom = dataFromChild;
  }
  render() {
    return (
      // Important! Always set the container height explicitly
      <div style={{ height: '100vh', width: '100%' }}>
        <GoogleMapReact
          bootstrapURLKeys={{ key: 'AIzaSyDs5u7u1Almh8-Jch3cHzuWB-egVPTZajs' }}
          defaultCenter={this.props.center}
          defaultZoom={this.props.zoom}
        >
          <AnyReactComponent
            lat={59.955413}
            lng={30.337844}
            text="My Marker"
          />
        </GoogleMapReact>
      </div>
    );
  }
}
export default SimpleMap;

我想使用:

 myCallbackMap = (dataFromChild:number) => {
    this.defaultProps.zoom = dataFromChild;
  }

在我的搜索栏中,以便当有人搜索它时会更改地图。

这是我的搜索文件(向下滚动以查看呼叫):

import * as React from 'react';
import axios from 'axios'
import Suggestions from './Suggestions'
import myCallbackMap from './Map'
const API_KEY:string = "process.env"
const API_URL:string = 'http://127.0.0.1:9001/v1/test'

export class Search extends React.Component{
  state = {
  query: '' as string,
    results : [] as any[]
  }
  search = {
    value: '' as string,
    }
  getInfo = () => {
    axios.post(`${API_URL}/${this.state.query}/`)
      .then(({ data }) => {
        this.setState({
          results: data.data
        })
      })
  }

  handleInputChange = () => {
    this.setState({
      query: this.search.value
    }, () => {
      if (this.state.query && this.state.query.length > 1) {
        if (this.state.query.length % 2 === 0) {
          this.getInfo()
        }
      } else if (!this.state.query) {
      }
    })
  }
  myCallbackSearch = (dataFromChild:string) => {
    this.search.value = dataFromChild;
// here where i want ot use the map call back
    myCallbackMap(111);

  }
  render() {
    return (
      <form>
        <input
          placeholder="Search for..."
          ref={input => this.search = input}
          onChange={this.handleInputChange}
        />
        <Suggestions results={this.state.results} callbackFromParentSearch={this.myCallbackSearch}/>
      </form>
    )
  }
}

export default Search

如何正确使用和导入地图,并在搜索组件中使用它?主要目标是,当有人在搜索栏中键入内容时,它将动态地更改地图。但是现在我正在研究一个简单的原型。

致谢

1 个答案:

答案 0 :(得分:0)

您无法导入它,因为当需要实例函数时它将是静态函数。

您必须将回调作为搜索组件的支持来传递。

回调本身实际上看起来像一个事件处理程序,其作用是更改其他组件中Google地图的默认属性(应声明为静态)。因此,我的猜测是您实际上并不想更改地图的默认道具,而是通过道具为其赋予新的缩放值。

您可以:

将公共祖先中的处理程序同时应用于搜索和地图组件,将zoom设为该公共祖先的状态,在回调中更新此状态,并通过props将该prop一直传播到搜索组件,以及缩放值一直到地图组件。

或者:

将此状态放置在redux商店中,这将允许您跳过道具链接并直接注册地图以侦听商店中的缩放更改,并将动作创建者传递给搜索组件,以便当搜索更改。

共同祖先版本:


    import * as React from 'react';
    import axios from 'axios';
    import Suggestions from './Suggestions'
    const API_KEY:string = "process.env"
    const API_URL:string = 'http://127.0.0.1:9001/v1/test'

    export class Search extends React.Component{
      state = {
        query: '' as string,
        results : [] as any[]
      }
      search = {
        value: '' as string,
      }
      getInfo = () => {
        axios.post(`${API_URL}/${this.state.query}/`)
          .then(({ data }) => {
            this.setState({
              results: data.data
            })
          })
      }

      handleInputChange = () => {
        this.setState({
          query: this.search.value
        }, () => {
          if (this.state.query && this.state.query.length > 1) {
            if (this.state.query.length % 2 === 0) {
              this.getInfo()
            }
          } else if (!this.state.query) {
          }
        })
      }
      myCallbackSearch = (dataFromChild:string) => {
        this.search.value = dataFromChild;
    // here where i want ot use the map call back
        myCallbackMap(111);

      }
      render() {
        const { callbackFromParentSearch } = this.props;
        return (
          <form>
            <input
              placeholder="Search for..."
              ref={input => this.search = input}
              onChange={this.handleInputChange}
            />
            <Suggestions results={this.state.results} callbackFromParentSearch={callbackFromParentSearch}/>
          </form>
        )
      }
    }

    export default Search;

请注意,下面的组件不需要具有完全相同的父代,这只是一个示例。如果您将道具从父级传递到子级,直到到达目标Search和SimpleMap,它仍然可以工作。

    export default class CommonAncestor extends Component {
        state: {
            zoom: 3 as number,
        }
        handleCallbackFromParentSearch = (dataFromChild:number) => {
            this.setState(() => ({ zoom: dataFromChild }));
        }
        render() {
            const { zoom } = this.state;
            return (
                <React.Fragment>
                    <Search callbackFromParentSearch={this.handleCallbackFromParentSearch} />
                    <SimpleMap zoom={zoom} />
                </React.Fragment>
            );
        }
    }

Redux版本:

连接到changeZoom操作的搜索组件


    import * as React from 'react';
    import axios from 'axios';
    import { connect } from 'react-redux';
    import Suggestions from './Suggestions';
    import { actionCreators as zoomAC } from 'src/redux/zoom';
    const API_KEY:string = "process.env"
    const API_URL:string = 'http://127.0.0.1:9001/v1/test'

    class Search extends React.Component{
      state = {
        query: '' as string,
        results : [] as any[]
      }
      search = {
        value: '' as string,
      }
      getInfo = () => {
        axios.post(`${API_URL}/${this.state.query}/`)
          .then(({ data }) => {
            this.setState({
              results: data.data
            })
          })
      }

      handleInputChange = () => {
        this.setState({
          query: this.search.value
        }, () => {
          if (this.state.query && this.state.query.length > 1) {
            if (this.state.query.length % 2 === 0) {
              this.getInfo()
            }
          } else if (!this.state.query) {
          }
        })
      }
      myCallbackSearch = (dataFromChild:string) => {
        this.search.value = dataFromChild;
    // here where i want ot use the map call back
        myCallbackMap(111);

      }
      render() {
        const { changeZoom} = this.props;
        return (
          <form>
            <input
              placeholder="Search for..."
              ref={input => this.search = input}
              onChange={this.handleInputChange}
            />
            <Suggestions results={this.state.results} callbackFromParentSearch={changeZoom}/>
          </form>
        )
      }
    }

    export default connect(
        null,
        dispatch => ({
            changeZoom: value => dispatch(zoomAC.changeZoom(value))
        })
    )(Search);

连接到缩放存储的SimpleMap组件:


    import * as React from 'react';
    import GoogleMapReact from 'google-map-react';
    import { connect } from 'react-redux';
    import { any } from 'prop-types';
    import {Coords} from 'google-map-react';
    export interface HelloProps { center: Coords ; zoom: number ; }


    const AnyReactComponent = ( {text} : { lat: any,text:any,lng:any}) => <div>{text}</div>;
    export class SimpleMap extends React.Component <HelloProps, {}> {
      defaultProps = {
        center: {
          lat: 59.95,
          lng: 30.33
        },
        zoom: 11
      };
      render() {
        return (
          // Important! Always set the container height explicitly
          <div style={{ height: '100vh', width: '100%' }}>
            <GoogleMapReact
              bootstrapURLKeys={{ key: 'AIzaSyDs5u7u1Almh8-Jch3cHzuWB-egVPTZajs' }}
              defaultCenter={this.props.center}
              defaultZoom={this.props.zoom}
            >
              <AnyReactComponent
                lat={59.955413}
                lng={30.337844}
                text="My Marker"
              />
            </GoogleMapReact>
          </div>
        );
      }
    }
    export default connect(
        state => ({ zoom: state.zoom })
    )(SimpleMap);