问题
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