Search code examples
javascriptreactjsoffice-ui-fabricoffice-fabric

Close MessageBar Office-UI-fabric from other component


Similar question have been asked, but it's not the same. Ref1: How we can close the error messagebar of office react fabric component? Ref2: Office ui fabric panel won't close

My question though is as follows. I'm adding MessageBars through a reduce and push in Parent component. I've moved _onDismiss to parent and i'm indexing the correct MessageBar when I mouse-click on the 'close' button. But how do i manage to both remove it from the array and also close it?

EDIT: I've managed to remove from array and also from the list on web. Only problem is that I still keep the last state that was added (from parent of MessageList). I'm working on a fix to remove the last element.

BONUS question: How can I add timer to info and success, but not to error?

I had to change from map to reduce since my code got swarmed with repeats since I'm not deleting from the array. If I do the same as the earlier stackoverflow posts all of the same gets deleted.

allFeedback is an array of objects containing an message back to the user and type 'error', 'success' or 'info'

Parent:

export def......
  super(); 
    this.state = {
      containerRef: React.createRef(),
      allFeedback: [],
    }
  } 

  _onDismiss = (index) => (ev) =>   {
    const allFeedback = this.state.allFeedback;
    allFeedback.splice(index, 1);
    allFeedback.pop();
    this.setState({ allFeedback });
  }

  <Portal>
    <MessageBox ref={this.state.containerRef}>
      {allFeedback.reduce((result, current, index) => {
        if (index < 15) {
          result.push(
            <Message 
             key={index}
             index={index} 
             message={current.message} 
             type={current.type}
             _onDismiss={this._onDismiss}
           />
         );
       }
      return result;
    }, [])}
    {/* Commented out code that breaks code with lots of repeats
      allFeedback.map((entry, index) => { 
        return <Message 
                 key={index} 
                 message={entry.message} 
                 type={entry.type} 
                />
        })
    */}
  </MessageBox>
</Portal>

Child component is the same for all, but different checks to see which one to add to screen.

{type === info ? (
  <StackItem>
    <MessageBar
      onDismiss={_onDismiss(index)}
      dismissButtonAriaLabel="Close"
    >
      {message}
    </MessageBar>
  </StackItem>
) : null}

I'm expected to remove it when i push the 'close' button and also remove it from the array. But since I cant do it - I'm stuck with loops going up to 30 after 3-4 clicks. Thats also why I've added the if in the code. But when I'm going to add a timer, it would be nice to also make it so that the timer removed it from the array.

EDIT: I've managed to remove from array and also web with the code under _onDismiss


Solution

  • SOLVED

    To remove the duplicate I checked so it didnt get passed twice.

      componentDidUpdate(prevProps, prevState) {
        if(this.props.feedback.message !== prevProps.feedback.message) {
          this.state.allFeedback.push(this.props.feedback)
        }
      }
    

    This made it so _onDismiss made an error, so i just cleaned it

      _onDismiss = (index) => () =>   {
        const allFeedback = this.state.allFeedback;
        allFeedback.splice(index, 1);
        this.setState({ allFeedback });
      }