ReactJS and Redux. How to highlight currently clicked element? - reactjs

For changing states I use redux. I have ChapterList Component where i iterate the list of chapters and display it , also I have Content Component where the content itself is displayed
On the left side i have list of topics, when I click on one of them,this topic's content is displayed on the right side. How to make also the topic from the left to be highlighted.
I want it to be highlighted like here.

I assume that your topic is a separate component, so you can pass 'isActive' prop to it and then in render function check for 'isActive' prop and add an 'active' class.
in Topic component:
render() {
const classes = this.props.isActive ? 'topic topic-active' : 'topic';
return (
<div className={classes} >
...

Related

Does it affect performance a lot to use redux state inside a element that is used many times?

I have a custom dropdown component to which a can pass a custom dropdown item. The problem is I have a case where I had to give some classes to the dropdown item based on redux store but I can't use it in the main dropdown component because that piece of state is not always used in the custom dropdown, a bad solution would be using the state inside the custom dropdown item but how can I do better because the custom dropdown item will be used a lot inside the custom dropdown component?
function CustomDropdown({listItem,onClick,options}){
let elements = options.map(el=>listItem(el,onClick));
return (
<ul>{elements}</ul>
)
}
function listItem(el,onClick){
return (
<li onClick={onClick} className={clsx(someReduxState&&"selected")} >{el}</li>
)
}
<CustomDropdown onClick={()=>{}} listItem={listItem} options=["1","2","3"] />

Mimic React custom component

I have a custom Reactjs component to display Pagination with next/previous buttons at the bottom of a grid. Now, the business needs to display the same component on top of the grid as well. How to display the previous /next button events based on the input provided in prev/next buttons at the bottom of the grid?
I tried using javascript innerHTML to mimic the behaviour. It works only with the display. It does not attach the event listener of the buttons. I tried even with
document.querySelector.addEventListener('click', ()=>{console.log('test')})
It does not work. Is there a better way to do with react.
I am going to just add some more content to Shmili Breuer answer.
If i understood you correctly you have 2 navigations, one at the top one at the bottom. The way you connect them would be through a state of you component, or a parent component if you are using functional component to render pagination stuff. So if you change the state it will reflect on both of your navigations. Also you can use only one function here, by passing a parameter, im gonna copy a code from before mentioned answer.
// first create a function
nextFunction = (condition) => {
if(condition){
this.setState(prevState=>({
page: prevState.page-1
}))
} else {
this.setState(prevState=>({
page: prevState.page+1
}))
}
}
// then use it in your button
<button onClick={() => this.nextFunction(some condition)}>Next</button>
Just put that component on top and bottom
<Grid>
<Pagination />
{...someOtherComponents}
<Pagination />
</Grid>
it's ok in react. Optimization that you want to do is overhead.
In react you would add an onClick attribute to an element you want to handle a click on.
Something like this
// first create a function
nextFunction = () => {
do next functionality....
}
// then use it in your button
<button onClick={() => this.nextFunction()}>Next</button>
This way you can have both top and bottom pagination call the same function.
Hope this helps

reusing stateful react components

I'm new to React and wanted some advice.
The problem is essentially thew following
I have a number of component buttons that open a modal, within this modal we have further buttons to offer a selection.
Home Screen Buttons (components)
<Button value="First"></button>
<Button value="Second"></button>
<Button value="Third"></button>.....
Modal.
<button value="Donald"></button>
<button value="Thomas"></button>
<button value="Evie"></button>.....
So the home screen buttons for example would have the following function, that it would pass down to the modal buttons onClick attribute.
selectPerson(e) {
setState({ selection : e.target.value})
}
So by selecting "First", we choose a person, close the modal, tie the selected person with Buttons state, and then repeat for second and so on.
Essentially these Buttons to open the modal have the same core functions (state and props). i.e I could have a template component an reuse it, but I would like each component to have independent state and props.
So I can achieve what I need but I've written each home screen button as an independent component, that is I've written a lot of the same code. If I attempt to reuse the SAME component, the are treated as the same component, and selecting a person changes all buttons state.
Is there anyway to avoid rewriting the same code for each (I have twenty). I've only just started (obviously) and am not too familiar with some of the more advanced concepts. If anyone has any suggestions or further questions, it would be great. I haven't provided code as the code works, its just extremely bulky
Yeah sure, define the button components and hand down certain elements inside its props.
You can then setState to be these handed down prop elements etc etc.
So define a button component with its various states defined by the props you hand it down. Then you have a mutable template Button component.
When you render these you just define its props.
<Button prop = "First" prop2 = "EXAMPLE"..../>
<Button prop = "Second" prop2 = "EXAMPLE2"..../>
<Button prop = "Third" prop2 = "EXAMPLE3"..../>
then inside the Button component use something like
this.state { property1 : this.props.prop, property2 : this.props.prop2 ...}
Hope this helps! I've recently been doing something similar

How to store the information in react component.

When I am asking this question, lots of doubts are coming into my mind. well, first I will give my problem description.
I have component X. and it contains checkboxes and a search box.
while something typed (call it search_query) in search box,
X needed to update the checkboxes which matches the search_query. [note that I got all the values of checkboxes by some api call. and it is done when component created. ]
First doubts I came to my mind is that
store (search_query) and (values of checkboxes) in component state
if the values are more searching takes more time.
is it possible to change the values of props inside the component
or is there any other way to do it ??
Since no code is shared. Assuming you are using plain React ( no Redux, middlewares are used ).
Answering your question:
[1] Is it possible to change the values of props inside the component?
Changing props values inside the component is a bad approach.
"All React components must act like pure functions with respect to their props."
[ref: https://facebook.github.io/react/docs/components-and-props.html#props-are-read-only]
Also, the view doesn't get the update if props values changed within the component.
[2] or is there any other way to do it.
yes ( without mutation inside the component )
using "state" property to hold values & setState to update values.
[3] How to store the information in react component?
Let's rename component X as FilterData,
searchbox ( SearchBox ) & checkboxes (SelectionBox) are two individual components.
// Define state to FilterData
class FilterData extends React.Component {
constructor() {
super()
this.state = {
term: '',
searchResults: []
}
}
....
}
// pass the state values to child components as props
class FilterData extends React.Component {
....
render() {
return (
<div>
<SearchBox term={this.state.term} />
<SelectionBox options={this.state.searchResults} />
</div>
)
}
}
In React App,
data flows top down (unidirectional) and there should be a single source of truth.
SearchBox & SelectionBox are two individual (sibling) components,
SearchBox's state has terms ( which has the search string )
When the user enters input SearchBox will update its state and possible to detect change event and fire ajax and get the response.
How SelectionBox can detect search that had happened, how it can get data.
This is why the state is moved to common ancestor FilterData.
[Ref: https://facebook.github.io/react/docs/lifting-state-up.html]
[Ref: https://facebook.github.io/react/docs/state-and-lifecycle.html#the-data-flows-down]
Code Sample -----------------------------------------------------
Selected values are not saved:
https://codepen.io/sudhnk/pen/NgWgqe?editors=1010
Selected values are saved:
https://codepen.io/sudhnk/pen/JJjyZw?editors=1010

Render selected item outside of input box for multi select of react-select library

How can we display the selected value just below the input box.
Use Case:
We are using multiple select of react-select , when we select the value from the select box , it comes inside the input box as selected. Can we have a method or something to get the selected values outside the input box (just below it)
Thanks in Advance!
I had a similar problem and I solved it creating a wrapper of react-select component and adding a state to my custom component. When the react-select changes I added the selected items to my component state and I show the in a custom div below, there you can add the styles that you want. Here an example of my approach: https://codesandbox.io/s/2kyy4998y
Hope this helps you.
Regards
I recently had to do this for a project I'm working on and wrote up how I did it here. The gist is that you need a wrapper component
// SelectWrapper.js
import ReactSelect from 'react-select'
const SelectWrapper = (props) => {
const { isMulti, value } = props;
return (
<div>
{isMulti ? value.map((val) => <span>{val.label}</span>) : null}
<Select {...props} controlShouldRenderValue={!isMulti} />
</div>
)
}
The very important part here is the controlShouldRenderValue prop which we disable when isMulti is true so the select dosn't show any selected values instead letting us take care of that

Resources