我有一个显示卡列表的组件。我正在尝试对表行进行排序,但是遇到了一些问题。当我转到页面时,出现以下错误:
错误:重新渲染次数过多。 React限制了渲染次数以防止无限循环。
它指向此行
setData(_.sortBy(filteredData.reverse()));
这是我的完整组件代码。谁能看到我要做什么的问题?
import React, { useState } from "react";
import Search from "./Search";
import TimeAgo from "react-timeago";
import { useSelector, useDispatch, connect } from "react-redux";
import { Table } from "semantic-ui-react";
import { searchChange } from "../reducers/searchReducer";
import _ from "lodash";
// import { useField } from "../hooks";
const searchCards = ({ baseball, search }) => {
return search
? baseball.filter(a =>
a.title[0].toLowerCase().includes(search.toLowerCase())
)
: baseball;
};
const Cards = props => {
const [column, setColumn] = useState(null);
const [direction, setDirection] = useState(null);
const [filteredData, setData] = useState(props.cardsToShow);
const handleSort = clickedColumn => {
if (column !== clickedColumn) {
setColumn(clickedColumn);
setData(_.sortBy(filteredData, [clickedColumn]));
setDirection("ascending");
return;
}
setData(_.sortBy(filteredData.reverse()));
direction === "ascending"
? setDirection("descending")
: setDirection("ascending");
};
return (
<>
<div>
<Search />
<h3>Vintage Card Search</h3>
<Table sortable celled fixed striped>
<Table.Header>
<Table.Row>
<Table.HeaderCell
sorted={column === "title" ? direction : null}
onClick={handleSort("title")}
>
Card Title
</Table.HeaderCell>
<Table.HeaderCell># Bids</Table.HeaderCell>
<Table.HeaderCell>Watchers</Table.HeaderCell>
<Table.HeaderCell>Price</Table.HeaderCell>
<Table.HeaderCell>Time Left</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{props.cardsToShow.map(card => (
<>
<Table.Row key={card.id}>
<Table.Cell>{card.title}</Table.Cell>
<Table.Cell>
{card.sellingStatus[0].bidCount
? card.sellingStatus[0].bidCount
: 0}
</Table.Cell>
<Table.Cell>
{card.listingInfo[0].watchCount
? card.listingInfo[0].watchCount
: 0}
</Table.Cell>
<Table.Cell>
$
{card.sellingStatus &&
card.sellingStatus[0].currentPrice[0]["__value__"]}
</Table.Cell>
<Table.Cell>
<TimeAgo
date={new Date(
card.listingInfo && card.listingInfo[0].endTime
).toLocaleDateString()}
/>
</Table.Cell>
</Table.Row>
</>
))}
</Table.Body>
</Table>
</div>
</>
);
};
const mapStateToProps = state => {
return {
baseball: state.baseball,
search: state.search,
cardsToShow: searchCards(state)
};
};
const mapDispatchToProps = {
searchChange
};
export default connect(mapStateToProps, mapDispatchToProps)(Cards);
// export default Cards;
答案 0 :(得分:3)
更改此行:
mRef = mDatabase.getReference("RestaurantUnu").child("Comenzi");
FirebaseRecyclerOptions<ReceivedCommandsModel> optionsReceivedCommands = new FirebaseRecyclerOptions.Builder<ReceivedCommandsModel>()
.setQuery(mRef, ReceivedCommandsModel.class)
.build();
adapterReceivedCommands = new FirebaseRecyclerAdapter<ReceivedCommandsModel, ReceivedCommandsViewHolder>(optionsReceivedCommands) {
@NonNull
@Override
public ReceivedCommandsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_command,parent,false);
layoutManagerOrder = new GridLayoutManager(parent.getContext(),3);
orderRecycler = (RecyclerView) itemView.findViewById(R.id.order_recycler);
orderRecycler.setLayoutManager(layoutManagerOrder);
fragmentItem = (LinearLayout)itemView.findViewById(R.id.item_layout);
return new ReceivedCommandsViewHolder(itemView);
}
@Override
protected void onBindViewHolder(@NonNull final ReceivedCommandsViewHolder receivedCommandsViewHolder, int i, @NonNull final ReceivedCommandsModel receivedCommandsModel) {
receivedCommandsViewHolder.tableNmb.setText(receivedCommandsModel.getMasa());
final FirebaseRecyclerOptions<Comanda> optionsOrderModel = new FirebaseRecyclerOptions.Builder<Comanda>()
.setQuery(mRef, Comanda.class)
.build();
adapterOrder = new FirebaseRecyclerAdapter<Comanda, OrderViewHolder>(optionsOrderModel) {
@NonNull
@Override
public OrderViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_order,parent,false);
//fragmentItem = (LinearLayout)itemView.findViewById(R.id.item_layout);
return new OrderViewHolder(itemView);
}
@Override
protected void onBindViewHolder(@NonNull final OrderViewHolder orderViewHolder, int i, @NonNull final Comanda orderModel) {
for(OrderModel order : orderModel.getcomanda()){
orderViewHolder.comandaTxt.setText(order.getdenumireProdus());}
}
};
adapterOrder.startListening();
orderRecycler.setAdapter(adapterOrder);
}
};
adapterReceivedCommands.startListening();
receivedCommandsRecycler.setAdapter(adapterReceivedCommands);
作者
add_filter( 'gravityflow_assignee_field_users', 'sh_gravityflow_assignee_field_users', 10, 3 );
function sh_gravityflow_assignee_field_users( $users, $form_id, $field ) {
$current_user = wp_get_current_user();
$users = array(
array( 'value' => 'user_id|'.$current_user->ID, 'text' => $current_user->display_name),
array( 'value' => 'user_id|2', 'text' => 'Joe' ),
array( 'value' => 'user_id|3', 'text' => 'Jane' ),
);
if ($users == jerry) {
return 400;
if ($users == Mary) {
return 600;
if ($users == Donald) {
return 340;
编辑:Reinis在下面写了一个很好的解释!
答案 1 :(得分:3)
Yachaka已经指出了错误的答案,但是他们的回答并未说明问题所在。
当您在React中使用prop={expression}
传递props时,括号中的表达式将被求值,就像传递函数参数时一样。因此,无论何时呈现组件,都将调用handleSort("title")
。然后,此功能将导致道具更新,并重新渲染组件,从而导致循环无限重复。
因此,问题在于,没有传递单击按钮时应调用的函数,而是调用了该函数(使用handleSort("title")
),结果为undefined
,并引起反馈循环。
您应该使用返回函数的表达式。正如Yachaka提到的() => handleSort("title")
一样,JavaScript中最简洁的方法是箭头功能。这将得出一个调用handleSort
的函数。