如何将反应路由器中的状态传递给组件

时间:2018-05-31 03:09:56

标签: reactjs

我试图制作一个单独的页面/组件进行搜索,我想知道如何将状态传递给另一个组件?我想将渲染/返回部分中的所有内容复制并粘贴到另一个组件中,然后使用反应路由器访问该页面,我该怎么做?任何帮助是极大的赞赏!

    import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Weather from "./Weather.js";
import Skycons from "react-skycons"
import { geticon } from "./geticon.js"

import ToggleDisplay from 'react-toggle-display';
import Form   from "./Form.js";
import Layout from "./layout.js";
import Hike  from "./Hike.js";
import 'bootstrap/dist/css/bootstrap.min.css';

import {FormControl, FormGroup, ControlLabel, HelpBlock, Checkbox, Radio, Button} from 'react-bootstrap';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";



const API_KEY = "2a41aeea56aabfb9ff1218730fc32426";

 class App extends React.Component {

  state = {
    temperature: "",
    city: "",
    city2:"",
    country: "",
    msg: "",
    pressure: "",
    humidity: "",
    description: "",
    rain:"",
    main:"Drizzle",
    icon: "09d",
    error: "",
    date: "",
    month:"",
    lat:"",
    show: false,
    lng:"",
    year:"",
    clouds:""

  }

  handlenum1Change (evt) {



let temp = (evt.target.value);




}

  getDate() {
   var date = new Date().getDate();
      var month = new Date().getMonth() + 1;
      var year = new Date().getFullYear();

   this.setState({ date,year,month});

}

 componentDidMount() {
    this.getDate();
  }


  getWeather = async (e) => {
    e.preventDefault();

      this.setState({ showResults: true });
    const city = e.target.city.value;

    const api_call = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${API_KEY}&units=metric`);
    https://www.hikingproject.com/data/get-trails-by-id?ids=7000108,7002175,7005207,7001726,7005428&key=YOU
    const data = await api_call.json();

    if (city) {
      this.setState({
        temperature: data.main.temp,
        city: data.name,
        clouds:data.clouds.all,
        main: data.weather[0].main,
        icon: data.weather[0].icon,
        rain: data.rain,
        pressure: data.main.pressure,
        humidity: data.main.humidity,
        description: data.weather[0].description,
        error: ""
      });

    } else {
      this.setState({
        temperature: undefined,
        city: undefined,
        country: undefined,
        humidity: undefined,
        description: undefined,
        pressure:undefined,
        rain : undefined,
        error: "Please enter the values."
      });
    }

var clouds= data.clouds.all;

if (clouds>30){
this.setState({
  msg:" Poor  conditions for stargazing!! "
})
}
  else{

   this.setState({
  msg: " Good conditions for stargazing! no rain in forecast! "
})
  }

}




  getTrail = async (e) => {
    e.preventDefault();


    const city = e.target.city2.value;
  this.setState({
      show: !this.state.show
    });

    const country = e.target.country.value;


    const api_call = await fetch(`https://api.wunderground.com/api/b1049a092a7f69ea/astronomy/q/${country}/${city}.json`);

    const data = await api_call.json();

   if (city) {
      this.setState({
        moon_phase: data.moon_phase.ageOfMoon,
        moon_hour: data.moon_phase.hemisphere,
          moon_rise: data.moon_phase.moonrise.hour,
           moon_rises: data.moon_phase.moonrise.minute,
        moon_state: data.moon_phase.phaseofMoon,
        moon_set: data.moon_phase.moonset.hour,
       moon_sets: data.moon_phase.moonset.minute,
        sunset: data.sun_phase.sunset.hour,
         sunsets: data.sun_phase.sunset.minute,
         sunrise:data.sun_phase.sunrise.hour,
         sunrises:data.sun_phase.sunrise.minute


      });
    } else {
      this.setState({
         moon_phase: undefined,
        sunset: undefined
      });
    }
  }




//   const BasicExample = () => (
//   <Router>
//     <div>
//       <ul className="navbar-nav ml-auto">

//         <li className="nav-item">
//           <Link to="/about">About</Link>
//         </li>
//         <li className="nav-item">
//           <Link to="/topics">Topics</Link>
//         </li>
//       </ul>

//       <hr />

//       <Route path="/about" component={About} />
//       <Route path="/topics" component={Topics} />
//     </div>
//   </Router>
// );


  render() {
    return (
      <div>


      <div>
        <br></br><br></br><br></br><br></br><br></br><br></br> 
      <div className="container">

    <div className="row">

      <div id="city">

              <div className="form-group mb-2">

                <div className="form-group mx-sm-3 mb-2">


                  <form className="form-inline" onSubmit={this.getWeather} >

                  <input type="text" name="city"  className="form-control" onChange={this.handlenum1Change} placeholder="Input City..."/>


    <button className="btn btn-primary">Get Weather</button>


    </form> 


                  <Weather className="fish"
                    city={this.state.city}
                    temperature={this.state.temperature}
                    humidity={this.state.humidity}
                 clouds={this.state.clouds}
                       pressure={this.state.pressure}
                    description={this.state.description}
                    rain={this.state.rain}
                    icon={this.state.icon}
                    error={this.state.error}
                  />

 <h3> {this.state.msg} </h3>

          <div className="clearfix"> 

      <div className="date"><p id="d"> {this.state.date}/{this.state.month}/{this.state.year}</p> 


<div>
    <Form getTrail={this.getTrail} />





              {this.state.moon_phase &&   <div> moon_phase: {this.state.moon_phase}</div>  }
               {this.state.sunset && this.state.sunsets && <div className="row"> <p> sunset Time: {this.state.sunset} </p> : <p> {this.state.sunsets} </p> </div> }

               {this.state.sunrise && this.state.sunrises &&  <div className="row"> <p> sunrise  Time: {this.state.sunrise} </p> : <p> {this.state.sunrises} </p></div> }

                   {this.state.moon_set && this.state.moon_sets && <div className="row"> <p> moonset:  {this.state.moon_set} </p> : <p> {this.state.moon_sets} AM</p> </div> }

                <div class="w-100"> </div>
                  {this.state.moon_rise && this.state.moon_rises &&    <div className="row">     <p>moonrise - {this.state.moon_rise} </p> : <p> {this.state.moon_rises} PM</p> </div> }



               {this.state.moon_state &&   <p> {this.state.moon_state} moon  </p> }
               {this.state.moon_hour && <p> hemisphere: {this.state.moon_hour} </p>  }
 </div>
 </div>
 </div>

</div>
</div>
 </div>

 </div>
 </div>
 </div>

 </div>


     );
  }
};

export default App;

5 个答案:

答案 0 :(得分:0)

如果我理解正确,那么您需要在render

中使用component代替react-router
  <Route path="/about" render={()=> <About parentState={this.state} />} />

您可以在关于

的组件中访问它们
this.props.parentState.main // should render "Drizzle"

答案 1 :(得分:0)

您需要将state作为道具发送到您想要使用Route渲染的组件, 那样:<Route path='/component' render={(props) => <MyComponent {...props} state={this.state} />} />

答案 2 :(得分:0)

首先。 传递状态:

将状态传递给其他组件的方法是使用react-redux

您设置了一个全局状态,然后通过connect

访问它

import { connect } from 'react-redux';

https://redux.js.org/basics/usage-with-react

-

其次。如果要在另一个组件中使用组件,只需调用该组件并传递道具即可。

超级基本示例。

import Products from '../../components/Products';
import ContentRow from '../../components/contentRow';

export default class Shop extends React.PureComponent {
  render() {

    return (

      <div>
        <ContentRow
         imageURL="https://placeimg.com/400/400/nature"
         shortText="This is the short text that will display"
        />
        <Products></Products>
      </div>
    );
  }
}

<contentRow shortText="...">是您要传递给渲染组件的props

希望这会有所帮助。

答案 3 :(得分:0)

首先在index.js文件中首先用<App>

包裹Router
    ReactDOM.render(
        <Router>
            <App />
        </Router>
      document.getElementById('root')
    );

第二步:在app.js的{​​{1}}中,您可以将所有内容都包含在render()中。在开关内部,您可以制作路线,每个路线都有您想要显示的任何组件。

<Switch>

那就是路由器的工作原理。对于你的另一个问题,有一些技巧给你,因为我不确定你需要什么:

只需将其作为道具发送到组件即可传递整个状态:

    render(){
        return(
            <div>
              <Switch>
                <Route exact path="/"> {/* needs to say "exact" for routes that 
                                         will be duplicated like "/" which is in 
                                         every route */}
                  <div>
                    <Weather/>
                    <Form/>
                  </div>
                </Route>

                <Route to="/">
                    <SearchComponent>
                </Route>
              </Switch>
            </div>
    )}

我怀疑这是最好的做法,但很高兴知道反应如何起作用。     如果你想改变子组件Weather的状态,你必须传递一个函数来处理类似于此的变化:

`<Weather state={this.state}/>`

天气:

    changeState = (newState) => {
        this.setState(newState);
    }
    <Weather state={this.state} changeParentState={this.changeState}/>
    enter code here

另一个反应提示是,如果你想在另一个组件中有一个组件,你可以这样做:

    componentDidMount() {
        this.setState({parentState: this.props.state)}
    }

And when you need to update the parent state : 

    this.props.changeParentState(newState);

并将<App> <ChildComponent/> </App> 放入this.props.children语句中,它将显示该组件!

Render

答案 4 :(得分:0)

想象一下:

我们将PageFour作为组件, 在此组件中,我们将“名称”作为“属性”。

我们需要将父级的“名称”传递给“ PageFour”组件。

首先,我们需要一个构造函数和父级中的super:

constructor(props) {
 super(props);
     this.state = {

         name:"anyname"

     }

}

然后在父级:

render() {
    return (
        <Router>
        <div className="container">


        <Route path="/user" component={() => (
            <PageFour  name={this.state.name}/> )}/>

        </div>
    </Router>
    );
}