ReactJS + React Router: how to refer to a specific object to pass as properties?

I currently have a table, and each cell has a button. After clicking a button depending on that day (Monday or Tuesday), class (class 1 or class 2) and name (Kev or Josh), how can I click the object associated with this particular button in the table on a new page? Using ReactJS + React Router, what would be the right approach to this?

And when, after moving to a new page, a new page will fill the table with class information from the transferred object associated with the click of a button.

code:

http://jsfiddle.net/k7wbzc4j/16/

If the data of the table rows should be structured and refer to an object based on an identifier, as shown below, or what would be a better structure, we would like to find this particular object based on the location of the cell (with day, name, and class number) ?

list: [ { name: Kev monday: { class1: { id: 0, classTitle: abc, number: class1, info: { time: 1, classSize: 2, } }, class 2: { id: 1, classTitle: def, number: class2, info: { time: 1, classSize: 2, } } }, tuesday: { class1: { id: 2, classTitle: ghi, number: class1, info: { time: 1, classSize: 2, } }, class 2: { id: 3, classTitle: jkl, number: class2, info: { time: 1, classSize: 2, } } }, }, { name: Josh, monday: { class1: { id: 4, classTitle: mno, number: class1, info: { time: 1, classSize: 2, } }, class2: { id: 5, classTitle: pqr, number: class2, info: { time: 1, classSize: 2, } } }, tuesday: { class1: { id: 6, classTitle: stu, number: class1, info: { time: 1, classSize: 2, } }, class2: { id: 7, classTitle: vwx, number: class2, info: { time: 1, classSize: 2, } } }, } } ] 

For example, if the Kev column in the Monday column, class1, would like to pass the details of the following to the next page:

 class1: { id: 0, classTitle: abc, number: class1, info: { time: 1, classSize: 2, } } 

Will accept and cancel the response. Thank you in advance

+5
source share
1 answer

Itโ€™s convenient to use a centralized state management tool like redux . You can send an action (something like SELECT_CLASS ) that sets the selected class to the repository and then reads that value from your new component. I would recommend this approach.

However, there is another way. Each browser history entry has a state concept. Therefore, when you move to a new route, you can save the selected data in the state for this history record, and then read it when the component displays. It will look something like this:

Save state:

 router.push({ to: '/path', state: class1 }); 

To read this:

 router.location.state 

React router docs: https://github.com/ReactTraining/react-router/blob/master/docs/API.md#pushpathorloc

UPDATE: Yay for redux! So, first we define the action + action for this:

 export const SELECT_CLASS = 'SELECT_CLASS'; export const selectClass = (class) => { return { type: SELECT_CLASS, class, } }; 

Now let's see how the gearbox handles this:

 import { SELECT_CLASS } from '/path/to/action' const selectedClass = ( state={}, action ) => { switch (action.type) { case SELECT_CLASS: return action.class; default: returns state; } }; 

Now, assuming you connected your components via response-redux as follows:

 // First argument is mapStateToProps, the second is mapDispatchToProps // https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options export default connect((state) => state, { selectClass } )(YourComponent); 

Here's how you set the selected class:

  // Wherever you need to navigate function eventHandler(e) { const { selectClass } = this.props; selectClass(class1); router.push('/next/location'); } 

And in the following component (which should also be connected, but does not require mapDispatchToProps :

 render() { const { selectedClass } = this.props; // do what you need with the class. } 

If you need help setting up a reaction + redux, the docs here are fantastic. If the ES6 syntax I used looks unfamiliar, babel docs are a good reference here

UPDATE 2: I took your fiddle and ran with it: http://jsfiddle.net/k7wbzc4j/17/ . Each button has a click event that will receive the correct object.

FINAL UPDATE: So, the summary of handleClick

 handleClick(e) { const classTitle = e.target.innerHTML; let obj = undefined; data.forEach((schedule) => { ['monday', 'tuesday'].forEach((day) => { const classes = schedule[day]; return Object.keys(classes).forEach((c) => { const cls = classes[c]; if (cls.classTitle === classTitle) { obj = cls; } }); }) }); if (obj) { // do your navigation here } } 

First we use forEach to iterate over the data array, which contains all the schedules. Then we monday over every day (currently only monday and tuesday ) to get all classes on that day for the current schedule. Then, since we do not know the names of all classes, we just grab all the keys (which are class names) and iterate over them. Finally, we can get the actual class objects and check if the classTitle one that was clicked. If so, we save this object until obj . At the very end, we guarantee that we have found a suitable object, and then we will do everything that is necessary for the correct processing of this click. This is pretty dirty, but necessary considering your data structure. I would recommend trying to save this data a little more relationally and store each element type separately (for example, Users , Classes , Days and Schedules objects are all in separate arrays with identifiers connecting them together)

In order to solve your problem that some of the classTitle will be the same, you also need to find out who was pressed (and maybe the day it was pressed). You can do this in several ways: add a data-user attribute to each button and capture it with a click, implement the concept of a โ€œselected userโ€, create a new component (possibly called UserSchedule ) that displays a row in this table and takes, as a requisite, custom classes. This way you will find out that any class that matches belongs to this user. Like I said: a few ways.

How, in order to show you how to transfer this to a new component, I demonstrated two ways above how to do it: through the state of the story or saving the value in the reduction reducer and getting it as a property. Doing more would equate me to solving the whole problem for you, which I will not do, since the only way this material is suitable is to do it yourself. Trust yourself, follow the recommendations that I gave, and use the Internet for any specific errors that you have, and you will get the most!

+4
source

Source: https://habr.com/ru/post/1261532/


All Articles