如何在Reactjs中从父组件的事件中调用子组件的方法 [英] how to call child component's method from parent component's event in Reactjs

查看:117
本文介绍了如何在Reactjs中从父组件的事件中调用子组件的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将该方法从父组件调用到子组件.

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

我已经进行了很多研究,但对于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;`

成员

    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>
      );
    }

我正在尝试实现此 https://codesandbox.io/s/runh6 功能这是重要的用户界面.我无法从父级到子级调用该方法. 在此操作中,我试图清除app.js click事件中的记录.有没有一种方法可以清除app.js中的数据.

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.

推荐答案

实际上,这些父级和子级组件结构不适合react想法. ReactJS仅建议从父级到子级的单向处理. 但是不用担心.

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.

您可以通过使用父级中的state值以及使用prop将父级函数传递给子级的方法来解决此问题.

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}/>

会员

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();
     } 
   });

这篇关于如何在Reactjs中从父组件的事件中调用子组件的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆