how to call child component's method from parent component's event in Reactjs

爷,独闯天下 提交于 2019-12-11 12:50:38

问题


Hi I am trying to call the method from parent component to child.

I have researched lot i didn't get any good solution with child(functional component). if there is a solution can any explain me to solve this.

APP.js

     import React from 'react';
        import IntegrationDownshift from './members'
        class App extends React.Component {
             constructor(props) {
              super(props);
              this.state = {
                 Name: "Name from state...",
                 Description: "Description from state...",
                Data:[data]
              }
           }
           Clear(){
    this.IntegrationDownshift.ClearRecord();     // Here I'm trying to call the method on such event  

 }
          render() {  
             return (
                <div>
         <IntegrationDownshift Members={this.state.Data}/>
          <Button variant="contained" color="secondary"  onClick={this.Clear.bind(this)} >  // when i click the button it will trigger
        clear         // when i click the button it will trigger
      </Button>
               </div>
             );
          }
        }

    export default App;`

members

    var suggestions = []
    var members=[];
    function renderInput(inputProps) {
      const { InputProps, classes, ref, ...other } = inputProps;
      return (
        <TextField
          InputProps={{
            inputRef: ref,
            classes: {
              root: classes.inputRoot,
              input: classes.inputInput,
            },
            ...InputProps,
          }}
          {...other}
        />
      );
    }
    function renderSuggestion(suggestionProps) {
      const { suggestion, index, itemProps, highlightedIndex, selectedItem } = suggestionProps;
      const isHighlighted = highlightedIndex === index;
      const isSelected = (selectedItem || '').indexOf(suggestion.label) > -1;
      return (
        <MenuItem
          {...itemProps}
          key={suggestion.label}
          selected={isHighlighted}
          component="div"
          style={{
            fontWeight: isSelected ? 500 : 400,
          }}
        >
          {suggestion.label}
        </MenuItem>
      );
    }
    renderSuggestion.propTypes = {
      highlightedIndex: PropTypes.number,
      index: PropTypes.number,
      itemProps: PropTypes.object,
      selectedItem: PropTypes.string,
      suggestion: PropTypes.shape({ label: PropTypes.string }).isRequired,
    };
    function getSuggestions(value, { showEmpty = false } = {}) {
      const inputValue = deburr(value.trim()).toLowerCase();
      const inputLength = inputValue.length;
      let count = 0;
      return inputLength === 0 && !showEmpty
        ? []
        : suggestions.filter(suggestion => {
            const keep =
              count < 5 && suggestion.label.slice(0, inputLength).toLowerCase() === inputValue;
            if (keep) {
              count += 1;
            }
            return keep;
          });
    }
    function DownshiftMultiple(props) {
        suggestions=props.Members;
      const { classes } = props;
      const [inputValue, setInputValue] = React.useState('');
      const [selectedItem, setSelectedItem] = React.useState([]);
      function handleKeyDown(event) {
        if (selectedItem.length && !inputValue.length && event.key === 'Backspace') {
          setSelectedItem(selectedItem.slice(0, selectedItem.length - 1));
        }
      }
       function ClearRecord(){     // ** trying to call this function **
       setSelectedItem(selectedItem.slice(0, selectedItem.length - selectedItem.length));
  }

      function handleInputChange(event) {
        setInputValue(event.target.value);
      }
      function handleChange(item) {
        let newSelectedItem = [...selectedItem];
        if (newSelectedItem.indexOf(item) === -1) {
          newSelectedItem = [...newSelectedItem, item];
          members=newSelectedItem;   // **want to send this**
           props.onDataChanged(members)// **here i'm trying to send the value**
        }
        setInputValue('');
        setSelectedItem(newSelectedItem);
      }    
      const handleDelete = item => () => {
        const newSelectedItem = [...selectedItem];
        newSelectedItem.splice(newSelectedItem.indexOf(item), 1);
        setSelectedItem(newSelectedItem);
      };    
      return (
        <Downshift
          id="downshift-multiple"
          inputValue={inputValue}
          onChange={handleChange}
          selectedItem={selectedItem}
        >
          {({
            getInputProps,
            getItemProps,
            getLabelProps,
            isOpen,
            inputValue: inputValue2,
            selectedItem: selectedItem2,
            highlightedIndex,
          }) => {
            const { onBlur, onChange, onFocus, ...inputProps } = getInputProps({
              onKeyDown: handleKeyDown,
              placeholder: 'Select multiple Members',
            });

            return (
              <div className={classes.container}>
                {renderInput({
                  fullWidth: true,
                  classes,
                  InputLabelProps: getLabelProps(),
                  InputProps: {
                    startAdornment: selectedItem.map(item => (
                      <Chip
                        key={item}
                        tabIndex={-1}
                        label={item}
                        className={classes.chip}
                        onDelete={handleDelete(item)}
                      />
                    )),
                    onBlur,
                    onChange: event => {
                      handleInputChange(event);
                      onChange(event);
                    },
                    onFocus,
                  },
                  inputProps,
                })}

                {isOpen ? (
                  <Paper className={classes.paper} square>
                    {getSuggestions(inputValue2).map((suggestion, index) =>
                      renderSuggestion({
                        suggestion,
                        index,
                        itemProps: getItemProps({ item: suggestion.label }),
                        highlightedIndex,
                        selectedItem: selectedItem2,
                      }),
                    )}
                  </Paper>
                ) : null}
              </div>
            );
          }}
        </Downshift>
      );
    }

    DownshiftMultiple.propTypes = {
      classes: PropTypes.object.isRequired,
    };

    const useStyles = makeStyles(theme => ({
      root: {
        flexGrow: 1,
        height: 250,
      },
      container: {
        flexGrow: 1,
        position: 'relative',
      },
      paper: {
        position: 'absolute',
        zIndex: 1,
        marginTop: theme.spacing(1),
        left: 0,
        right: 0,
      },
      chip: {
        margin: theme.spacing(0.5, 0.25),
      },
      inputRoot: {
        flexWrap: 'wrap',
      },
      inputInput: {
        width: 'auto',
        flexGrow: 1,
      },
      divider: {
        height: theme.spacing(2),
      },
    }));

    let popperNode;

    export default function IntegrationDownshift(props) {
        debugger
      const classes = useStyles();
      const Members=props.Members;
       props.onDataChanged("test")

      return (
        <div className={classes.root}>

          <DownshiftMultiple classes={classes} Members={Members}  />

        </div>
      );
    }

I'm trying to implement this https://codesandbox.io/s/runh6 functionality which is material UI. I'm not able to call the method from parent to child. in this operation i'm trying to clear the records in app.js click event. Is there a way to clear the data in app.js.


回答1:


In fact, these parent and child components structure does not fit into the react idea. ReactJS only recommends one-way processing from parent to child. But do not worry.

You can solve this by using the state value in the parent and the method of passing the parent's function to the child using props.

App.js

this.state = {
   Name: "Name from state...",
   Description: "Description from state...",
   Data:[data],
   resetFlag: false,
}
...
setReset = () => {
   this.setState(prevState => ({ resetFlag: !prevState.resetFlag }));
};
...
// this.IntegrationDownshift.ClearRecord(); you can't call children's function directly
if(!this.state.resetFlag) {
   this.setReset();
}
...
// then pass state value and function to child.
<IntegrationDownshift Members={this.state.Data} resetFlag={this.state.resetFlag} setReset={this.setReset}/>

Members

function DownshiftMultiple(props) {
...
   // hook props changes
   React.useEffect(() => {
     // component updated
     if(props.resetFlag) {
        // This is the place where you can clear your data
        ClearRecord();
        // set resetFlag as false to prevent erasing your data again.
        props.setReset();
     } 
   });



回答2:


React doesn’t really do that. What you’ll need to implement is the parent having the selectedItem in its state and then pass that to the child via props. Any functions that update this value need to be passed from the parent to the child as prop callback functions. This way the parent has all the functionality it needs to control the child and the child just renders what is passed in via props.



来源:https://stackoverflow.com/questions/56817610/how-to-call-child-components-method-from-parent-components-event-in-reactjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!