javascript - React component function call only updates one component instance - TagMerge
3React component function call only updates one component instanceReact component function call only updates one component instance

React component function call only updates one component instance

Asked 11 months ago
0
3 answers

Although you use the component 3 times, it doesn't mean that a change you make in one of the components will be reflected in the other 2, unless you specifically use a state parameter that is passed to all 3 of them.

Also, the way you add the active class is not recommended since you mix react with pure js to handle the CSS class names.

I would recommend having a single click handler that toggles the active class for all n RightTab components:

const MainComponent = () => {
  const [classNames, setClassNames] = useState([]);
  
  const handleClick = (name) => 
  {
    const toggledActiveClass = classNames.indexOf('active') === -1
      ? classNames.concat(['active'])
      : classNames.filter((className) => className !== 'active');
      
    setClassNames(toggledActiveClass);
    
    switch (name) {
      case 'Dashboard';
        // do something
        break;
        
        case 'Inventory':
        // ....
        break;
    }
  }
  
  const dataArray = [
    {
      name: "Dashboard",
      icon: Assets.Dashboard,
      dropDown: false,
      onClick: handleClick.bind(null, 'Dashboard'),
    },
    {
      name: "Inventory",
      icon: Assets.Inventory,
      dropDown: true,
      onClick: handleClick.bind(null, 'Inventory'),
    },
    {
      name: "Reports",
      icon: Assets.Reports,
      dropDown: true,
      onClick: handleClick.bind(null, 'Reports'),
    },
  ];

  return (
    <>
      {dataArray.map((data) => 
        <RightTab key={data.name} 
                  data={data} 
                  classNames={classNames} />)}
    </>
  );
};

const RightTab = ({ data, classNames }) => {
  return (
    <div className={classNames.concat(['RightTab flex__container']).join(' ')} 
         onClick={data.onClick}>
      <img src={data.icon} alt="Dashboard Icon" />
      <p className="p__poppins">{data.name}</p>
      {data.dropDown === true ? (
        <div className="dropdown__icon">
          <img src={Assets.Arrow} alt="Arrow" />
        </div>
      ) : (
        <div className="nothing"></div>
      )}
    </div>
  );
};

Source: link

0

Pass event handlers and other functions as props to child components:
<button onClick={this.handleClick}>
Bind in Constructor (ES2015)
class Foo extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={this.handleClick}>Click Me</button>;
  }
}
Class Properties (Stage 3 Proposal)
class Foo extends Component {
  // Note: this syntax is experimental and not standardized yet.
  handleClick = () => {
    console.log('Click happened');
  }
  render() {
    return <button onClick={this.handleClick}>Click Me</button>;
  }
}
Bind in Render
class Foo extends Component {
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={this.handleClick.bind(this)}>Click Me</button>;
  }
}
Arrow Function in Render
class Foo extends Component {
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={() => this.handleClick()}>Click Me</button>;
  }
}

Source: link

0

In this traditional UI model, it is up to you to take care of creating and destroying child component instances. If a Form component wants to render a Button component, it needs to create its instance, and manually keep it up to date with any new information.
class Form extends TraditionalObjectOrientedView {
  render() {
    // Read some data passed to the view
    const { isSubmitted, buttonText } = this.attrs;

    if (!isSubmitted && !this.button) {
      // Form is not yet submitted. Create the button!
      this.button = new Button({
        children: buttonText,
        color: 'blue'
      });
      this.el.appendChild(this.button.el);
    }

    if (this.button) {
      // The button is visible. Update its text!
      this.button.attrs.children = buttonText;
      this.button.render();
    }

    if (isSubmitted && this.button) {
      // Form was submitted. Destroy the button!
      this.el.removeChild(this.button.el);
      this.button.destroy();
    }

    if (isSubmitted && !this.message) {
      // Form was submitted. Show the success message!
      this.message = new Message({ text: 'Success!' });
      this.el.appendChild(this.message.el);
    }
  }
}
When an element’s type is a string, it represents a DOM node with that tag name, and props correspond to its attributes. This is what React will render. For example:
{
  type: 'button',
  props: {
    className: 'button button-blue',
    children: {
      type: 'b',
      props: {
        children: 'OK!'
      }
    }
  }
}
This element is just a way to represent the following HTML as a plain object:
<button class='button button-blue'>
  
    OK!
  
</button>
However, the type of an element can also be a function or a class corresponding to a React component:
{
  type: Button,
  props: {
    color: 'blue',
    children: 'OK!'
  }
}
This feature lets you define a DangerButton component as a Button with a specific color property value without worrying about whether Button renders to a DOM <button>, a <div>, or something else entirely:
const DangerButton = ({ children }) => ({
  type: Button,
  props: {
    color: 'red',
    children: children
  }
});

Source: link

Recent Questions on javascript

    Programming Languages