I'm quite new to ReactJS and I have trouble understand how different components can communicate with each other.
I do have a component that will render a list and each list item is a different component. I want to keep the components as small as possible.
Now, each list item can have a property named active
and if the property is set to true, an additional class is added.
This is the class that defines a single item in the component.
See this below code for my component defining a single list item:
export default class OfficeRibbonTab extends React.Component {
constructor(props) {
super(props);
this.state = {
active: props.active ? props.active : false
}
// Assign all the correct event handlers.
this.setActive = this.setActive.bind(this);
}
setActive() {
this.setState({active: true});
}
render() {
// When the tab is defined as active, add the "active" class on it.
if (this.state.active)
{ var tabClassName = "active"; }
return <li onClick={this.setActive} className={tabClassName}>{this.props.tabName}</li>;
}
}
So, I have propery active
which is passed to this component, which I store in the components state.
When I click the list item, I set to state of the current item to be active.
The problem is that I want all the other list items to become inactive, thus setting the state of active to false.
The code below is an overview of my list:
export default class OfficeRibbon extends React.Component {
constructor(props) {
// Call the 'base' constructor.
super(props);
}
render() {
var tabs = [];
// Loop over all the tab elements and define how the element should be rendered.
for (var i = 0; i < this.props.dataSource.tabs.length; i ++)
{
if (i == 1)
{ tabs.push(<OfficeRibbonTab active={true} key={this.props.dataSource.tabs[i].name} tabName={this.props.dataSource.tabs[i].name}></OfficeRibbonTab>); }
else
{ tabs.push(<OfficeRibbonTab key={this.props.dataSource.tabs[i].name} tabName={this.props.dataSource.tabs[i].name}></OfficeRibbonTab>); }
}
return (<div>
<div className="wrap-top">
<OfficeRibbonTitle title={this.props.title}/>
<ul className="tabs">
{tabs}
</ul>
</div>
</div>);
}
}
It doesn't seem like rocket science, but I want to do it the React way without re-inventing the wheel.
Anyone who can guide me in the right direction?
Kind regards
To implement the change of item on click, we will create the list data as a state in react by using the useState hook. Then on onClick we will change the item. Step 3: Create folder components inside src folder of react project directory and inside the components folder create files List. jsx.
To render a list dynamically in React, we start by adding a property to the state object. We can populate that property with an array of strings like so. Great. Now we want to move to the render() method to render each list item dynamically.
We have to set initial state value inside constructor function and set click event handler of the element upon which click, results in changing state. Then pass the function to the click handler and change the state of the component inside the function using setState.
js - Input editable UI import React, { useState } from "react"; import Editable from "./Editable"; function App() { // State for the input const [task, setTask] = useState(""); /* Enclose the input element as the children to the Editable component to make it as inline editable.
It looks like OfficeRibbonTab
manages its own state, which is fine, but it never informs its parent component of the state change. The most common approach would be to supply a callback function to each child component, so that it can then communicate back to the parent:
For example, OfficeRibbon
will now contain a function handleTabSelect
that gets passed down as a prop to each OfficeRibbonTab
. And in OfficeRibbonTab
, when a tab is clicked, you simply invoke the callback, and pass in the selected tab's index or id:
OfficeRibbonTab.jsx
setActive(tabIndex) {
this.props.handleTabSelect(tabIndex);
}
OfficeRibbon.jsx
handleTabSelect(tabIndex) {
this.setState({activeIndex: tabIndex});
}
Now in OfficeRibbon
, you update your state to set the activeIndex
or activeId
, again either by the index or an identifier of your choosing. By setting state in OfficeRibbon
, we necessarily force a render()
of its children. As a result, we simply match the index of the iterator with the activeIndex
of your state, when we iterate in render()
:
<OfficeRibbonTab active={index === this.state.activeIndex} onClick={this.handleTabSelect} ... />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With