在onClick时使用参数对Js setState进行反应 [英] React Js setState with params when onClick

查看:68
本文介绍了在onClick时使用参数对Js setState进行反应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Reactjs制作一个简单的相册列表,单击每个项目后,我必须获取该相册的所有照片,因此我想更改状态(album_Id). 问题是我无法更改状态,并且我不知道如何独立加载第二页(以显示一张相册的所有照片). 请我帮忙.

I am using Reactjs to make a simple list of albums and after a click on each item I have to get all photos of this album, so I think to change the state (album_Id) .. the problem is I can't change the state and I dont know how to load the second page (to display all photo of one album) independently. please I need your help.

这是我的代码(App.js):

this is my code (App.js):

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import Photolist from './photolist';
// import logo from './logo.svg';
import './App.css';

class App extends Component {
  constructor(props){
        super(props);
        this.state = {
          currentAlbumId: null,
          CurrentPhotoId: null
        };
        this.updateCurrentAlbum = this.updateCurrentAlbum.bind(this);
    }

  updateCurrentAlbum(id) {
    this.setState({currentAlbumId : id})
  }

  render() {

    const tab_albums = [
      {
        "albumId": 1,
        "id": 1,
        "title": "accusamus beatae ad facilis cum similique qui sunt",
        "url": "http://placehold.it/600/92c952",
        "thumbnailUrl": "http://placehold.it/150/92c952"
      },
      {
        "albumId": 1,
        "id": 2,
        "title": "reprehenderit est deserunt velit ipsam",
        "url": "http://placehold.it/600/771796",
        "thumbnailUrl": "http://placehold.it/150/771796"
      },
      {
        "albumId": 2,
        "id": 66,
        "title": "provident rerum voluptatem illo asperiores qui maiores",
        "url": "http://placehold.it/600/ee0a7e",
        "thumbnailUrl": "http://placehold.it/150/ee0a7e"
      },
      {
        "albumId": 2,
        "id": 67,
        "title": "veritatis labore ipsum unde aut quam dolores",
        "url": "http://placehold.it/600/1279e9",
        "thumbnailUrl": "http://placehold.it/150/1279e9"
      }
    ]; 
    const albumsIds = [];
    
    tab_albums.map((album_model) => {
        return (
            albumsIds.indexOf(album_model.albumId) === -1 ? albumsIds.push(album_model.albumId) : null
        )
    });

    var album_style = {"background": "#cccccc", "marginBottom": "10px", "borderLeft": "5px solid red"};
    var style_div = {"width": "50%", "float": "left"};

    const liste_album = albumsIds.map((alb_id) => {
          return (
            <Router key={alb_id}>
                <li style={album_style} >
                    <Link to={"/photolist/"+alb_id} onClick={() => this.updateCurrentAlbum(alb_id)}>
                    Album : { alb_id }
                    </Link>
                    <Route path="/photolist" component={Photolist}/>
                </li>
            </Router> 
          )
    });
  return (
    <div className="App">
      <div style={style_div}>
         <ul>{liste_album}   </ul>
      </div>
      <div style={style_div}>
        <button>wishlist</button>
      </div>
    </div>
    ); 
  }
}
export default App;

推荐答案

似乎您将链接与您认为应该是路由器信息的内容一起呈现,但这并不是它的工作原理

It seems like you render your links together with the what you believe should be the Router information, but that is not really how it works

但是,您应该做的是独立渲染链接,并查看照片列表中的一项,以在渲染应用程序中添加匹配的路线.

What you should do however is render the links independently, and to view one item of your fotolist, to add a matching route in your rendering app.

因此,请更改链接的呈现方式,

So change the rendering of your links, like so:

const liste_album = albumsIds.map((alb_id) => {
      return (
            <li style={album_style} key={alb_id}>
                <Link to={"/photolist/"+alb_id}>
                Album : { alb_id }
                </Link>
            </li>
      )
});

删除onClick处理程序,这是由Link组件完成的.导航时,您的应用程序将知道浏览器位置已更改.要显示当前的活动路线,您应该像这样更改渲染(请注意,此处已定义路由器,并且您仅应定义模板路径以匹配活动路线,或根据需要定义确切的路径)

Removing the onClick handler, as this is done by the Link component. When it navigates, your app would know that the browser location has changed. To show the current active route, you should change your render some like this (note that the Router is defined here, and that you should just define a template path to match the active Route, or an exact path, depending on your need)

return (
  <Router>
    <div className="App">
      <div style={style_div}>
        <ul>{liste_album}</ul>
      </div>
      <div style={style_div}>
        <button>wishlist</button>
      </div>
      <Route path="/photolist/:id" render={({match}) => <Photolist alb_id={match.params.id} />
    </div>
  </Router>
  ); 
}

此行

<Route path="/photolist/:id" render={({match}) => <Photolist alb_id={match.params.id} />

将找到具有参数的任何路径,并将呈现特定的组件.目前,我沿着alb_id前进,但是您可以选择搜索匹配的相册,然后将其传递给照片列表".

will find any path that has a parameter and will render a certain component. At the moment I am passing along the alb_id, however you could choose to search for the matching album, and pass that to the Photolist.

或者,您也可以将路径创建为:

Alternatively, you could also create the path as:

<Route path="/photolist/:id" component={Photolist} />

并使用

And export the Photolist component (which would be a single album, I guess) with the withRouter Higher Order Function, which would enable you to get the params at least from the router props. However, that wouldn't completely work in your current setting, as your code seems to mix data with rendering and state mapping. This is well, not perfect. Your component also seems to do way to much.

您实际上应该从刚刚显示的一个组件中创建3个或4个组件,例如,检查此版本的照片列表:

You should really create 3 or four components from that one component you have just shown, as an example, check this version of your photolist:

// just some imports matching with the cdn packages
const { Route, withRouter } = ReactRouter;
const { Link } = ReactRouterDOM;
const { createStore, combineReducers } = Redux;
const { Provider, connect } = ReactRedux;
const { Component } = React;

const Router = ReactRouter.MemoryRouter;

const tab_albums = [
  {
    "albumId": 1,
    "id": 1,
    "title": "accusamus beatae ad facilis cum similique qui sunt",
    "url": "http://placehold.it/600/92c952",
    "thumbnailUrl": "http://placehold.it/150/92c952"
  },
  {
    "albumId": 1,
    "id": 2,
    "title": "reprehenderit est deserunt velit ipsam",
    "url": "http://placehold.it/600/771796",
    "thumbnailUrl": "http://placehold.it/150/771796"
  },
  {
    "albumId": 2,
    "id": 66,
    "title": "provident rerum voluptatem illo asperiores qui maiores",
    "url": "http://placehold.it/600/ee0a7e",
    "thumbnailUrl": "http://placehold.it/150/ee0a7e"
  },
  {
    "albumId": 2,
    "id": 67,
    "title": "veritatis labore ipsum unde aut quam dolores",
    "url": "http://placehold.it/600/1279e9",
    "thumbnailUrl": "http://placehold.it/150/1279e9"
  }
]; 

const albumsReducer = (state = tab_albums, action) => {
  // currently not doing anything specials, so just load the albums in the state
  return state;
}

// the store will trigger all changes down to any components intrested in it, thanks to the Provider component
const store = createStore( combineReducers({ albums: albumsReducer }) );

// redux helper to match state to the props, so that components can access the defined properties inside its props
const albumsStateToProps = state => ({ albums: state.albums });

// the album is a purely stateless component, it simply receives the props it should show
const Album = ({ albums, currentAlbumId }) => {
  // get the album based on the passed currentAlbumId
  let album = albums.find(a => {
    return a.id == currentAlbumId;
  });
  return <div>
    <h1>Album: {album.title}</h1>
    <div>
      <a href={album.url} target="_blank"><img src={album.thumbnailUrl} alt="album image" /></a>
    </div>
    <Link to="/">Back to mainpage</Link>
  </div>;
};

const ConnectedAlbum = connect( albumsStateToProps )( Album );

// the location is received thanks to the withRouter higher order function
const PathViewer = ({location}) => {
  return <span>{ location.pathname }</span>;
};

// this creates a new component that extends the props of the PathViewer
const RouterPathViewer = withRouter( PathViewer );

// the overview component will receive the albums through its props, and just needs to map it
const Overview = ( {albums} ) => {
  return <ul>{albums && albums.map( ({id, title}) => <li><Link to={`/album/${id}`}>{ title }</Link></li> ) }</ul>;
};

// the ConnectedOverview gets its props thanks to the albumsStateToProps method defined above
// this means that the Overview component will have access to props.albumns
const ConnectedOverview = connect(albumsStateToProps)(Overview);

// this is the layout component, it enables the routing, and shows the main page
class AlbumViewer extends Component {
  render() {
    return <Router>
      <div>
        <h1>Album viewer</h1>
        <span>Current path: <RouterPathViewer /></span>
        <Route path="/" exact={true} component={ConnectedOverview} />
        <Route path="/album/:id" render={({match}) => {
          return <ConnectedAlbum currentAlbumId={match.params.id} />;
        } }/>
      </div>
    </Router>;
  }
}

// this creates the rendering, where the Provider will rerender components depending on it based on changes on the store
ReactDOM.render( <Provider store={store}><AlbumViewer /></Provider>, document.querySelector('#container') );

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/4.2.0/react-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router-dom/4.2.2/react-router-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.6/react-redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.7.2/redux.min.js"></script>
<div id="container"></div>

我欢迎您完成我制作的小型演示,或者如果您对设置有疑问,以及为什么要运行这个小型应用程序需要这么多软件包,请随时试用它;)

I welcome you to finish the small demo I made, or if you might have questions towards the setup, and why so many packages are need to run this small app, so feel free to play around with it ;)

这篇关于在onClick时使用参数对Js setState进行反应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆