React-Router:使用链接从一个组件传递props到另一个组件

4

我创建了一个包含3个页面的应用程序,Home、Reptiles和Map。

我的问题出现在Reptiles和Map页面上。在爬行动物页面上,我显示了一系列物种列表,每个列表都有一系列分布国家和一个“查看地图”链接。当用户点击一个国家时,我希望地图页面显示选定的国家高亮显示(目前还没有实现,所以我只想将该国家传递到地图页面)。

当用户点击某个物种的“查看地图”时,我希望地图页面显示该物种的所有分布国家都被突出显示。目前,我可以在react-router的路由中传入reptile和country属性,但是当我尝试直接在Reptlie.js文件中的链接中传递属性时,我会收到错误警告:Unknown prop reptile on tag。从元素中删除此属性。有人能帮我解决如何直接向组件中的链接传递props的问题吗?还有,你如何生成动态URL?例如,map/species1或map/country1?

我认为我的问题在于Reptiles.js。使用的react-router版本是3.0.2。

下面是我的结构:

enter image description here

下面是一些图片: enter image description here enter image description here

下面是我的代码:

router.js:

const routes = (
  <Router history={browserHistory}>
    <Route component={App}>
        <Route path="/" component={Home}/>
        <Route path="reptiles" name="reptiles" component={Reptiles}/>
        <Route path="map" name="map" component={Map} country="Taiwan" reptile="Beardy"/>
    </Route>
  </Router>
);

export default routes;

App.js:

class App extends Component {
  render() {
    return (
      <div className="container">
        <header>
          <span className="icn-logo"><i className="material-icons">code</i></span>
          <ul className="main-nav">
            <li><NavLink to="/">Home</NavLink></li>
            <li><NavLink to="/reptiles">Reptiles</NavLink></li>
            <li><NavLink to="/map">Map</NavLink></li>
          </ul>       
        </header>
        {this.props.children}

      </div>
    );
  }
}

export default App;

Reptiles.js:

const Reptiles = () => {
  let reptiles = ReptileList.map((reptile) => {
    return (
      <li className="reptile" key={reptile.id} >
        <img className="reptile-img" src={reptile.img_src} />
        <h3>{reptile.name}</h3>
        <h4> Range &nbsp; &nbsp; 
            <span className="seeMap">
                <NavLink to="map" reptile={reptile.id}>  
                See Map Here 
                </NavLink>
            </span>
        </h4> 
            {reptile.range.map(function(country,index) {
                // only add comma if it's not the last one
                return <span key={country}><NavLink to="map" country={country}> {(index < reptile.range.length-1)? country+',' : country} </NavLink></span> 
            })
            }

      </li>
    );
  }); 

  return (
    <div className="main-content">
      <h2>Reptiles</h2>
      <ul className="group">
        {reptiles}    
      </ul>
    </div>
  );
}

export default Reptiles;

Map.js

var Map = React.createClass({

  render: function() {


    return (
        <div>
            <h2>Country passed from props: {this.props.route.country} </h2>
            <h2>Reptile passed from props: {this.props.route.reptile} </h2>
        </div>
    )

    }

});



export default Map;

我将所有的代码和地图页面的目标添加到了这个仓库的 readme 中:https://github.com/jhjanicki/react-reptile-app - jhjanicki
3个回答

7
在route.js中,你可以按照以下方式传递参数:
<Route path="map/:countryName/:reptileId" component={Map} name="map" />

在Reptile.jsx中,将从props.country或从state存储的参数传递。确保在链接中传递一些默认值,以防不适用。例如,在第一个链接中的国家,我已经传递了所有。您可以根据需要传递参数,可以传递以下参数:
<NavLink to={`map/${reptile.id}`}>      

<NavLink to={`map/${country}/${reptile.id`}>

你可以在Map.jsx中通过上下文访问这些参数,例如this.props.params.reptileId

关于参数的更多信息

就像在你的情况中一样,reptile id参数在两种情况下都是必需的,而country参数仅在单击特定国家时需要。因此,你可以将country参数设置为可选项,而reptile id参数则必须。你可以参考这个链接

<Route path="map/:reptileId(/:countryName)" component={Map} name="map" /> 

然后相应地传递。
<NavLink to={`map/${reptile.id}`}>      

<NavLink to={`map/${reptile.id}/${country}`}> 

我测试了一下,为了简单起见,我只尝试了爬行动物。在router.js中,我将路由更改为:<Route path="map/:reptileId" component={Map} name="map" />,在Reptiles.js中,我将NavLink更改为<NavLink to="map/${reptile.id}">查看地图</NavLink>,但是我收到了这个错误:警告:[react-router]位置“/map”没有匹配任何路由。但是我没有任何指向“map”的链接。有什么想法吗? - jhjanicki
爬虫的ID有没有任何值? - Richa Garg
这是我在网址中得到的内容:http://localhost:8080/map/$%7Breptile.id%7D,但地图页面无法打开。如果您需要更多详细信息,我创建了一个GitHub仓库github.com/jhjanicki/react-reptile-app。 - jhjanicki
当然。让我检查一下! - Richa Garg
谢谢您的帮助,出于某些原因我一直无法让它正常工作。我将尝试重写 ES5 代码,看看是否有所改善。 - jhjanicki
显示剩余3条评论

1

您有三个选择:

  1. 将参数放入URL中。这是默认的最佳选择。 例如,您可以使用url /map/beardy/map?name=beardy
    然后在Map中使用props.params.whatever或解析props.location.search(例如使用npm的qs)访问这些内容。

  2. 使用browserHistory.pushstate参数,它会添加一个隐藏的数据到历史记录框架中。这保留了刷新页面、向前和向后浏览历史记录时保留数据的能力。缺点是我不能将链接发送给其他人并使其加载所选内容。

  3. 使用redux或类似工具将数据存储在内存中。当页面刷新时,数据将丢失。这非常糟糕。


如果我对Reptiles.js进行更改:<NavLink to="map/{reptile.id}">在这里查看地图</NavLink>和<NavLink to="map/{country}">,那么我需要对router.js进行哪些更改?目前的Map路由是<Route path="map" name="map" component={Map} country="Taiwan" reptile="Beardy"/>,但当我仅编辑Reptiles.js时,它仍然无法正常工作。如何同步它们?这是尝试第一种选项,我还没有尝试第二和第三种。 - jhjanicki
@jhjanicki path="map/:foo" 然后它将是 props.params.foo - Brigand

0

关于你的第一个问题:“如何直接在组件中传递属性?”。你不能直接传递,但有一些解决办法,就像其他答案中提到的那样,可以创建一个含有数据的URL,并在加载组件时从URL中获取数据。但你无法通过<Link><a>传递自定义属性。

不过,你可以像在router.js中所做的那样传递自定义属性,只是要改为:

这段内容来自你的router.js

<Route path="reptiles" name="reptiles" component={Reptiles}/>

你可以像这样传递props:
<Route path="/reptiles" render={() => <Reptiles name="reptiles" />} />

关于您的第二个问题:“如何生成动态URL?”

假设您正在呈现组件,像这样在div中:
class App extends Component {
    render() {
        return (
            <Reptile subtype="foobar" />
        )
    }
}

然后在Reptile.js中,您可以创建像这样的动态URL:

class Reptile extends Component {
    render() {
        return (
            <div>
                <NavLink to={`/reptile/${this.props.subtype}`} />
            </div>
        )
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接