0

In my application I have multiple blocks generated dynamically and each one of them has an onClick event.

My goal is to be able to change the contents of the div when the click happens.

Is there a way to do this thru event.target property of the onClick event?

Or should i create a ref for each div upon creation and then work with refs?

Or should i create an array of Div elements in component state and search&modify the element later re-rendering all divs from array?

1
  • It's primarily opinion-based, but changing state in response to the click event and let the component re-render itself with the new state is the most common way of doing it, like you outlined in your last question. Commented Nov 15, 2018 at 18:07

2 Answers 2

2

Since blocks are generating dynamically, have onClick event on children components.

const Parent = () => {
  return (
    <Child content={content} contentAfterClick={content} />
    <Child content={content} contentAfterClick={content} />
  )
}


class Child extends Component {
  constructor() {
    super();
    this.state ={
      read: false,
    };
  }

 render() {

   if (this.state.read) {
     return(
       <div>{this.props.contentAfterClick}</div>
     )
   }

   return (
     <div onClick={() => this.setState({ read: true })}>
       <div>{this.props.content}</div>
     </div>
   );
 };
}
Sign up to request clarification or add additional context in comments.

Comments

1

This demo illustrates how you can change the contents of a div, the text, when a click happens through the onClick and event.target object as you wanted.

You can do this through the use of refs, but normally you want to avoid refs unless absolutely necessary because there are easier ways to accomplish the same thing in React.

Also wouldn't want to keep the physical DOM nodes, HTMLDivElement, in state. Instead, keep the contents it relies upon in state (in our case a single number value), then when you change the contents it will automatically update and rerender our div nodes.

// Example class component
class Container extends React.Component {
  constructor(props) {
    super(props);
    const blocks = [];
    blocks.push(0);
    blocks.push(0);
    blocks.push(0);
    this.state = { blocks: blocks, clickedElementContents: "" };
  }
 
  increment(event, index) {
    const newBlocks = this.state.blocks;
    newBlocks[index]++;
    this.setState({ blocks: newBlocks, clickedElementContents: event.target.innerText });
  }
 
  render() {
    return (
      <div>
        <div className="block" onClick={(event) => { this.increment(event, 0) }}>Click me! ({this.state.blocks[0]})</div>
        <div className="block" onClick={(event) => { this.increment(event, 1) }}>Click me! ({this.state.blocks[1]})</div>
        <div className="block" onClick={(event) => { this.increment(event, 2) }}>Click me! ({this.state.blocks[2]})</div>
        <span>Contents of the clicked element: {this.state.clickedElementContents}</span>
      </div>
    );
  }
}

// Render it
ReactDOM.render(
  <Container/>,
  document.body
);
.block {
  display: inline-block;
  background-color: black;
  color: white;
  padding: 5px;
  margin-right: 10px;
}
<div id="react"></div>
<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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.