将道具从组件传递到同级组件的子级?

时间:2020-04-15 17:24:25

标签: reactjs

// App.js

import React from 'react';
import logo from './logo.svg';
import './App.css';
import Map from "./Map.js"
import Search from "./Search"
import Navbar from "./Navbar"
import Footer from "./Footer"
import Sidebar from "./Sidebar"


class App extends React.Component {



  constructor(props) {
    super(props);

    this.state = {

      isLoaded: false
    }

    this.loadScript = this.loadScript.bind(this);
    this.scriptLoaded = this.scriptLoaded.bind(this);

  }

  scriptLoaded() {
    this.setState({ isLoaded: true });

  }

  loadScript() {

    const API_KEY = process.env.REACT_APP_API_KEY;
    const url = `https://maps.googleapis.com/maps/api/js?key=${API_KEY}&libraries=places`;

    const s = document.createElement("script");
    s.src = url;
    document.head.appendChild(s);
    s.onload = this.scriptLoaded;
  }

  componentWillMount() {

    this.loadScript();

  }


  render() {

    return (

      <div>

        <Navbar />



        <div className="row">

          <div className="col-md-9">
            {this.state.isLoaded && <Map />}
          </div>

          <div className="col-md-3">

            {this.state.isLoaded && <Search />}

            <Sidebar />

          </div>
        </div>

        <Footer />

      </div>


    );

  }
}

export default App;

//Map.js

import React from "react"
import Marker from "./Marker"

export default class Map extends React.Component {

    constructor(props) {
        super(props);

        this.state = {

            map: null,
            lat: '',
            lng: ''
        }

        this.loadMap = this.loadMap.bind(this);
    }

    loadMap() {

        const map = new window.google.maps.Map(document.getElementById('map'), {
            center: { lat: -34.397, lng: 150.644 },
            zoom: 8
        });

        this.setState({ map: map });
        let self = this;
        window.google.maps.event.addListener(map, 'click', function (event) {
            self.setState({ lat: event.latLng.lat(), lng: event.latLng.lng() });



        });



    }








    componentDidMount() {

        this.loadMap();





    }


    render() {




        return (

            <div>
                <div id="map" style={{ height: window.innerHeight, width: "100%" }}></div>


                {this.state.lat && <Marker lat={this.state.lat} lng={this.state.lng} map={this.state.map} />}

            </div>

        );

    }




}

//Sidebar.js

import React from 'react'

export default class Sidebar extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            logo: ''
        }

        this.handleClick = this.handleClick.bind(this);
    }

    handleClick(logo) {
        this.setState({ logo: logo });
    }

    render() {

        return (

            <div>
                <p style={{ fontFamily: "os" }}>Choose a Marker</p>
                <img onClick={(e) => this.handleClick("v", e)} style={{ height: "150px", width: "150px" }} src={process.env.PUBLIC_URL + 'markervm.png'} />
                <img onClick={(e) => this.handleClick("s", e)} style={{ height: "150px", width: "150px" }} src={process.env.PUBLIC_URL + 'markersm.png'} />
            </div>

        );

    }


}

//Marker.js

import React from 'react'



export default class Marker extends React.Component {

    addMarker() {
        const latlng = { lat: this.props.lat, lng: this.props.lng }

        console.log(latlng);

        const marker = new window.google.maps.Marker({
            position: latlng,
            map: this.props.map,
            title: 'Hello World!'
        });


    }

    componentDidMount() {


    }

    render() {

        this.addMarker();
        return null;
    }

}

更新 我添加了代码。很多。我希望可以在Marker.js中访问Sidebar.js的状态

我有三个组成部分,我们称它们为A,B和C。

组件A渲染组件B并将道具传递给它。组件C是独立的。如何将组件C的状态传递给组件B?

组件A和C是同级。组件B是组件A的子代。

2 个答案:

答案 0 :(得分:0)

您可以通过多种方式执行此操作:

  • 在组件C中创建prop方法,以更新组件B中的状态
  • 使用react上下文
  • 使用Redux存储区

第一种方法的示例:

export class A extends Component {

  public state;
  constructor(props){
    super(props);
    this.state = {
      bState: {}
    }
  }

  render() {
    return <B updateStateA={(state) => {this.setState({bState: state}}><B/>
  }

}


export class B extends Component {

 public state;
  constructor(props){
    super(props);
    this.state = {
      loaded: false
    }
  }

  componentDidMount(){
    this.setState({loaded:true});
    this.props.updateStateA(this.state);
  }

  render() {
    return <div>This Is Component B</div>
  }  

}

答案 1 :(得分:0)

请检查以下完整示例:

父组件::它正在传递函数回调(setOpeningValue),以便子组件调用此函数将值传递给父组件。

import React, {useEffect, useState} from 'react';
import Child from "./Child";
import Sibling from "./Sibling";

function CParent(props) {

    const [status, setStatus] = useState(false);

    function setOpeningValue(status) {
        console.log(status);
        setStatus(status);
    }
    return (
        <div>
            <Child setOpeningValue={setOpeningValue}/>
            <Sibling status={status}/>
        </div>
    );
}
export default CParent;

子组件:它正在调用setOpeningValue将该值传递给父组件。

import React, {useEffect, useState} from 'react';

// Child to Parent communication
function Child(props) {
    const {setOpeningValue} = props;
    const [isOpen, setOpen] = useState(false);

    function clickHandler() {
        setOpen(!isOpen);
        setOpeningValue(!isOpen);
    }
    return (
        <div>
            <button onClick={clickHandler}>Open</button>
        </div>
    );
}
export default Child;

同级组件:使用其父级传递的道具中的状态。

import React, {useEffect, useState} from 'react';

function Sibling(props) {
    const {status} = props;
    const [isOpen, setOpen] = useState(false);

    return (
        <div>
            {status}
        </div>
    );
}
export default Sibling;