D. Messier
D. Messier

Reputation: 235

React, dynamically add text to ref span

I'm trying to render a message to a span tag specific to an item in a list. I've read a lot about React 'refs', but can't figure out how to populate the span with the message after it's been referenced.

So there's a list of items and each item row has their own button which triggers an API with the id associated with that item. Depending on the API response, i want to update the span tag with the response message, but only for that item

When the list is created the items are looped thru and each item includes this

<span ref={'msg' + data.id}></span><Button onClick={() => this.handleResend(data.id)}>Resend Email</Button>

After the API call, I want to reference the specific span and render the correct message inside of it. But I can't figure out how to render to the span at this point of the code. I know this doesn't work, but it's essentially what I am trying to do. Any ideas?

if (response.status === 200) {
    this.refs['msg' + id] = "Email sent";

Upvotes: 5

Views: 14887

Answers (3)

amdev
amdev

Reputation: 7460

i was facing with this issue right now and i figured it out this way:

// currentQuestion is a dynamic Object that comes from somewhere and type is a value
const _target = `${currentQuestion.type}_01` 
const _val = this[`${_target}`].current.clientHeight // here is the magic

please note that we don't use . after this to call the ref and not using refs to achieve what we want.
i just guessed that this should be an Object that would hold inner variables of the current object. then since ref is inside of that object then we should be able to call it using dynamic values like above...

i can say that it worked automagically!

Upvotes: 0

ramki
ramki

Reputation: 481

The workaround is set innerText

   this.refs['msg' + id].innerText = "Email sent";

But rather than using ref try to use state to update elements inside render.

Upvotes: 2

seunggabi
seunggabi

Reputation: 1822

I recommand using state. because string refs legacy (https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs)

const msgs = [
    { id:1, send:false },
    { id:2, send:false },
    { id:3, send:false },
];

this.state = {
    msgs
};

return this.state.msgs.map((msg, index) => {
    const status = msg.send ? "Email Sent" : "";
    <span>{ status }</span><Button onClick={() => this.handleResend(index)}>Resend Email</Button>
});

async handleResend (index) {
    const response = await callAPI(...);
    if(reponse.status !== 200) return;

    const newMsgs = _.cloneDeep(this.state.msgs);
    newMsgs[index].send = true;
    this.setState({
        msgs: newMsgs
    })
}

Upvotes: 3

Related Questions