我正在努力制定出可能非常简单的方法。我的父组件是一个搜索窗口小部件,它需要使用在单独的抽屉组件中定义的过滤器。当前,用户可以键入搜索查询,该查询调用一个API,并且需要基于抽屉组件中的选择器来过滤结果。但是,我无法链接父母和孩子来实现这一目标!
父组件(其中包括''组件):
function SuburbSearch(props: Props) {
const classes = useStyles();
const [value, setValue] = React.useState<App.Suburb | null>(null);
const [inputValue, setInputValue] = React.useState('');
...
return (
<Autocomplete
id="search"
getOptionLabel={(option) => (typeof option === 'string' ? option : option.name + ' ' + option.state)}
filterOptions={(x) => x}
options={options}
...
...
renderInput={(params) => (
<TextField
{...params}
label="Search for a suburb"
...,
startAdornment: (
<InputAdornment position="start">
<Filters></Filters>
</InputAdornment>
),
endAdornment: (
<React.Fragment>
{loading ? <CircularProgress color="inherit" size={20} /> : null}
{params.InputProps.endAdornment}
</React.Fragment>
),
}}
fullWidth
/>
)}
子组件(这是“过滤器”):
export default function Filters() {
const classes = useStyles();
const [state, setState] = useState(false);
const [dollar, setDollars] = useState<number[]>([0, 20000000]);
const [type, setType] = React.useState<string | null>('all');
...
const list = (anchor: Anchor) => (
<div className={classes.root}
role="presentation" /*onClick={toggleDrawer(false)} onKeyDown={toggleDrawer(false)}/*/>
<Grid className={classes.main} container spacing={2}>
<Grid className={classes.row} item xs={1} md={2} />
<Grid className={classes.row} item xs={10} md={8}>
<Typography className={classes.header} align='center' gutterBottom>
Property Type
</Typography>
<ToggleButtonGroup value={type} onChange={handleTypeChange} exclusive>
<ToggleButton value="all" >All</ToggleButton>
<ToggleButton value="some" >Some</ToggleButton>
</ToggleButtonGroup>
</Grid>
...
</Grid>
</div>
}
答案 0 :(得分:1)
您可以简单地通过将函数作为道具来实现,就像这样:
父组件
@extends('layouts.master')
@section('content')
{{--//Blade view--------------------------------------------------------------------------------------------------------}}
<div class="">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-lg-12 borrower_id">
<div class="pull-left">
<h2>Pending Loans</h2>
</div>
</div>
<div class="col-xs-3 col-sm-3 col-md-3 " >
<h6>Branch</h6>
<input class="form-control" type="text" placeholder="Branch Name" aria-label="Search" id="branch_selector" name="branch_selector" value="" >
</div>
<div class="col-xs-3 col-sm-3 col-md-3" >
<h6>Center</h6>
<input class="form-control" type="text" placeholder="Center Name" aria-label="Search" id="center_selector" name="center_selector" value="" >
</div>
<div class="col-xs-3 col-sm-3 col-md-3" >
<h6>Group</h6>
<input class="form-control" type="text" placeholder="Group Number" aria-label="Search" id="group_selector" name="group_selector" value="">
</div>
<div class="col-xs-3 col-sm-3 col-md-3" >
<h6>Search</h6>
<button type="submit"><i class="fa fa-search"></i></button>
</div>
</div>
</div>
</div>
</div>
{{-- @if ($message = Session::get('success'))
<div class="alert alert-success">
<p>{{ $message }}</p>
</div>
@endif --}}
<table class="table table-bordered" id="loan_table">
<tr>
<th>No</th>
<th>Borrower No</th>
<th>Loan Stage</th>
<th>Loan Amount</th>
<th>Release Date</th>
<th width="200px">Action</th>
</tr>
@foreach ($loans as $loan)
<tr>
<td>{{ ++$i }}</td>
<td>{{ $loan->borrower_no }}</td>
<td>{{ $loan->loan_stage }}</td>
<td>{{ $loan->loan_amount }}</td>
<td>{{ $loan->release_date }}</td>
<td width="100px">
<form action="{{ route('approving.destroy',$loan->borrower_no) }}" method="POST">
<a class="btn btn-info btn-sm" href="{{ route('approving.show',$loan->borrower_no) }}">Details of Borrower</a>
{{--<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" >Show</button>--}}
<a class="btn btn-success btn-sm" href="/approving/test/{{$loan->borrower_no}}">Approve</a>
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger btn-sm">Reject</button>
</form>
</td>
</tr>
@endforeach
</table>
{!! $loans->links() !!}
-------------------Ajax part---------------------
@section('scripts')
<script type="text/javascript">
$(document).ready(function () {
$(group_selector).click(function () {
var group = $(this).val();
console.log(group);
var tmp = null;
$.ajax({
type: 'GET',
url: '{{ ('/gseclector') }}',
data: {'id':group},
dataType: 'JSON',
success: function (data) {
console.log(data);
data.forEach(function(item){
$('#loan_table').append('$loans'+item);
})
});
}
});
});
});
</script>
子组件
childCallback(value) {
// value passed from child
}
return {
<ChildComponent passToParent={this.childCallback}/>
}
答案 1 :(得分:1)
在这里,我正在为您提供Pure React中的一些基本状态管理技术,因为到目前为止,我是通过在注释部分与您讨论而了解的。
假设您有一个组件comp1
,它有一些道具,其中包括需要直接来自其子组件的数据的方法,比如说Comp2
:
const Comp1 = ({ onActionOrChild }) => {
return (
<>
<Comp2 onAction={onActionOrChild} />
</>
)
}
const Comp2 = ({ onAction }) => {
return (
<form onSubmit={onAction}>
...
</form>
)
}
简而言之,这里有一个组件,该组件需要来自其后代之一的某些数据,例如一些表单数据,因此我们将其传递给了这些子对象。但是这里的问题是 道具钻探 ,Comp1
需要获得一个它从未使用过的道具。
现在,反应 Context API 是稳定的,它对于实现以前需要其他状态管理库的功能非常强大。
版本16.3引入了新的上下文API,该API效率更高, 支持静态类型检查和深度更新。 -Docs
如果我们使用上下文API,则可以从组件中提取这些方法并将其放入一个新文件中,这将创建上下文提供程序,以便应用程序中的不同组件可以彼此通信,而无需传递道具到从未使用过的中间组件到组件之间的几级下降。
Context.js
export const AppContext = createContext();
export AppContextProvider = ({children}) => {
const onAction = () => {}
return (
<AppContextProvider.Provider
value={{onAction}}
>
{children}
</AppContextProvider.Provider>
)
}
现在,如果我们需要在应用程序的任何部分中使用一种方法,我们只需连接 context API :
import { AppContext } from "./Context.js"
const comp3 = ({}) => {
const { onAction } = useContext(AppContext);
return (
<form onSubmit={onAction}>
...
</form>
)
}