Reactjs 在react中使用map函数时,如何仅传递相关道具?
我有一个ReviewList组件,它通过数据库映射,并用评论列表填充页面。在每个评论中,我还传递一个编辑模式组件,在其中我尝试传递道具。我面临的问题是,试图只通过与具体审查相适应的道具。相反,它传递映射的每个审阅的道具,因此当尝试在编辑模式组件中编辑审阅时,它总是修改第一个审阅,因为它是道具列表中的第一个审阅。例如,当I console.log _idprop时,我会收到映射的每个评论的_id,而不仅仅是单击编辑按钮的特定评论的_id 审阅列表组件:Reactjs 在react中使用map函数时,如何仅传递相关道具?,reactjs,react-props,map-function,Reactjs,React Props,Map Function,我有一个ReviewList组件,它通过数据库映射,并用评论列表填充页面。在每个评论中,我还传递一个编辑模式组件,在其中我尝试传递道具。我面临的问题是,试图只通过与具体审查相适应的道具。相反,它传递映射的每个审阅的道具,因此当尝试在编辑模式组件中编辑审阅时,它总是修改第一个审阅,因为它是道具列表中的第一个审阅。例如,当I console.log _idprop时,我会收到映射的每个评论的_id,而不仅仅是单击编辑按钮的特定评论的_id 审阅列表组件: import { Link } from '
import { Link } from 'react-router-dom';
import { Modal, Button } from "react-bootstrap";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Edit from "../Edit/index";
import Auth from "../../utils/auth";
const ReviewList = ({ reviews, profileReviewEdit }) => {
const [showEditModal, setShowEditModal] = useState(false);
const reload = () => window.location.reload();
if (!reviews.length) {
return (
<h1 className='pageText'>No Reviews Yet</h1>
)
}
return (
<>
<div className="containter center">
{reviews && reviews.map((review) => (
<div className='row bloc-box'>
<div className='col-3'>
<Link to={`/gamepage/${review.gameId}`}>
<img src={`${review.gameCoverUrl}`}
fluid
thumbnail
width={200}
/>
</Link>
<Link to={`/gamepage/${review.gameId}`}>
<h5 className='game-title'>{review.gameTitle}</h5>
</Link>
</div>
<div className='col'>
<h3 className='col'>
<p className='review-title'>{review.title}</p>
</h3>
<div className="pl-3">
<p className="username-link">
Written by: <Link
to={`/profile/${review.username}`}
style={{ fontWeight: 700 }}>
{review.username}
</Link>{' '} on {review.createdAt}
</p>
</div>
<div>
<div className="col-9">
<h4 className='review-text'>{review.reviewBody}</h4>
</div>
</div>
<div className='col-9'>
{[...Array(parseInt(`${review.rating}`))].map((star, i) => {
const ratingValue = i + 1;
return (
<label>
<input
type='radio'
name='rating'
value={review.rating}
/>
<FontAwesomeIcon className='star'
icon='star'
size='lg'
color={review.rating ? '#ffc107' : '#e4e5e9'}
/>
</label>
)
})}
</div>
<p className='small-title'> {review.rating}/5 Stars </p>
</div>
<div>
{Auth.loggedIn(), profileReviewEdit &&
<div>
<Button variant="outline-warning" size='sm' onClick={() => setShowEditModal(true)}>
<FontAwesomeIcon icon="edit" color="#FEBE10" size="lg" />Edit</Button>{' '}
</div>}
</div>
<div >
<Modal
size="lg"
show={showEditModal}
onHide={() => setShowEditModal(false)}
onExit={reload}
>
<Modal.Header closeButton>
<Modal.Title>Edit Review</Modal.Title>
</Modal.Header>
<Modal.Body>
<Edit
handleModalClose={() => setShowEditModal(false)}
_id={review._id}
reviewTitle={review.title}
reviewBody={review.reviewBody}
setShowEditModal={setShowEditModal}
/>
</Modal.Body>
</Modal>
</div>
</div>
))}
</div>
</>
)
};
export default ReviewList;
import { useMutation } from "@apollo/react-hooks";
import { EDIT_REVIEW, DELETE_REVIEW } from "../../utils/mutations";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
const Edit = ({ _id, reviewTitle, reviewBody, setShowEditModal }) => {
console.log(_id);
const [ editReview ] = useMutation(EDIT_REVIEW);
const [ deleteReview ] = useMutation(DELETE_REVIEW);
const [title, setTitle] = useState("");
const [titleCharacterCount, setTitleCharacterCount] = useState(0);
const [editBody, setEditBody] = useState("");
const [editBodyCharacterCount, SetEditBodyCharacterCount] = useState(0);
console.log(editBody);
const [rating, setRating] = useState(null);
const [hover, setHover] = useState(null);
console.log()
const handleTitleChange = (event) => {
if (event.target.value.length <= 30) {
setTitle(event.target.value);
setTitleCharacterCount(event.target.value.length);
}
};
const handleEditBodyChange = (event) => {
if (event.target.value.length <= 1000) {
setEditBody(event.target.value);
SetEditBodyCharacterCount(event.target.value.length);
}
};
const handleFormSubmit = async (event) => {
event.preventDefault();
// reviewBody = editBody;
try {
await editReview({
variables: { _id:_id, title:title, reviewBody:editBody, rating:rating },
});
// clear form value
setTitle("");
setTitleCharacterCount(0);
setEditBody("");
SetEditBodyCharacterCount(0);
setShowEditModal(false);
} catch (e) {
console.error(e);
}
};
const handleDelete = async ( _id ) => {
console.log(_id)
try {
await deleteReview({
variables: { _id },
});
setShowEditModal(false);
} catch (e) {
console.error(e);
}
}
const StarRating = () => {
return (
<div>
{[...Array(5)].map((star, i) => {
const ratingValue = i + 1;
return (
<label>
<input
type='radio'
name='rating'
value={ratingValue}
onClick={() => setRating(ratingValue)}
/>
<FontAwesomeIcon className='star'
icon='star'
size='2x'
color= {ratingValue <= (hover || rating) ? '#ffc107' : '#e4e5e9'}
onMouseEnter={() => setHover(ratingValue)}
onMouseLeave={() => setHover(null)}
/>
</label>
)
})}
<h5> {rating}/5 Stars </h5>
</div>
)
}
return (
<div>
<form
className="flex-row justify-center justify-space-between-md align-stretch"
onSubmit={handleFormSubmit}
>
<textarea
placeholder={reviewTitle}
value={title}
className="form-input col-12 col-md-9"
onChange={handleTitleChange}
></textarea>
<p className={`m-0 ${titleCharacterCount === 30 ? "text-error" : ""}`}>
Character Count: {titleCharacterCount}/30
</p>
<textarea
placeholder={reviewBody}
value={editBody}
className="form-input col-12 col-md-9"
onChange={handleEditBodyChange}
></textarea>
<p
className={`m-0 ${editBodyCharacterCount === 1000 ? "text-error" : ""
}`}
>
Character Count: {editBodyCharacterCount}/1000
</p>
<StarRating />
{/* {error && <span className="ml-2">Something went wrong...</span>} */}
<button className="btn btn-success col-12 col-md-3" type="submit">
Submit
</button>
</form>
<button className="btn btn-danger mt-1 col-12 col-md-3" type="button" onClick={() => handleDelete(_id)}>
Delete Review
</button>
</div>
);
}
export default Edit;
从'react router dom'导入{Link};
从“react bootstrap”导入{Modal,Button};
从'@fortawesome/react fontawesome'导入{FontAwesomeIcon};
从“./编辑/索引”导入编辑;
从“../../utils/Auth”导入授权;
const ReviewList=({reviews,profileReviewEdit})=>{
const[showEditModal,setShowEditModal]=useState(false);
const reload=()=>window.location.reload();
如果(!reviews.length){
返回(
还没有评论
)
}
返回(
{reviews&&reviews.map((review)=>(
{review.gameTitle}
{review.title}
作者:
{review.username}
{review.createdAt}上的{'}
{review.reviewBody}
{[…数组(parseInt(`${review.rating}')].map((星形,i)=>{
常数值=i+1;
返回(
)
})}
{review.rating}/5星
{Auth.loggedIn(),profileReviewEdit&&
setShowEditModal(真)}>
编辑{'}
}
setShowEditModal(假)}
onExit={reload}
>
编辑评论
setShowEditModal(假)}
_id={review.\u id}
reviewTitle={review.title}
reviewBody={review.reviewBody}
setShowEditModal={setShowEditModal}
/>
))}
)
};
导出默认审阅列表;
编辑组件:
import { Link } from 'react-router-dom';
import { Modal, Button } from "react-bootstrap";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Edit from "../Edit/index";
import Auth from "../../utils/auth";
const ReviewList = ({ reviews, profileReviewEdit }) => {
const [showEditModal, setShowEditModal] = useState(false);
const reload = () => window.location.reload();
if (!reviews.length) {
return (
<h1 className='pageText'>No Reviews Yet</h1>
)
}
return (
<>
<div className="containter center">
{reviews && reviews.map((review) => (
<div className='row bloc-box'>
<div className='col-3'>
<Link to={`/gamepage/${review.gameId}`}>
<img src={`${review.gameCoverUrl}`}
fluid
thumbnail
width={200}
/>
</Link>
<Link to={`/gamepage/${review.gameId}`}>
<h5 className='game-title'>{review.gameTitle}</h5>
</Link>
</div>
<div className='col'>
<h3 className='col'>
<p className='review-title'>{review.title}</p>
</h3>
<div className="pl-3">
<p className="username-link">
Written by: <Link
to={`/profile/${review.username}`}
style={{ fontWeight: 700 }}>
{review.username}
</Link>{' '} on {review.createdAt}
</p>
</div>
<div>
<div className="col-9">
<h4 className='review-text'>{review.reviewBody}</h4>
</div>
</div>
<div className='col-9'>
{[...Array(parseInt(`${review.rating}`))].map((star, i) => {
const ratingValue = i + 1;
return (
<label>
<input
type='radio'
name='rating'
value={review.rating}
/>
<FontAwesomeIcon className='star'
icon='star'
size='lg'
color={review.rating ? '#ffc107' : '#e4e5e9'}
/>
</label>
)
})}
</div>
<p className='small-title'> {review.rating}/5 Stars </p>
</div>
<div>
{Auth.loggedIn(), profileReviewEdit &&
<div>
<Button variant="outline-warning" size='sm' onClick={() => setShowEditModal(true)}>
<FontAwesomeIcon icon="edit" color="#FEBE10" size="lg" />Edit</Button>{' '}
</div>}
</div>
<div >
<Modal
size="lg"
show={showEditModal}
onHide={() => setShowEditModal(false)}
onExit={reload}
>
<Modal.Header closeButton>
<Modal.Title>Edit Review</Modal.Title>
</Modal.Header>
<Modal.Body>
<Edit
handleModalClose={() => setShowEditModal(false)}
_id={review._id}
reviewTitle={review.title}
reviewBody={review.reviewBody}
setShowEditModal={setShowEditModal}
/>
</Modal.Body>
</Modal>
</div>
</div>
))}
</div>
</>
)
};
export default ReviewList;
import { useMutation } from "@apollo/react-hooks";
import { EDIT_REVIEW, DELETE_REVIEW } from "../../utils/mutations";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
const Edit = ({ _id, reviewTitle, reviewBody, setShowEditModal }) => {
console.log(_id);
const [ editReview ] = useMutation(EDIT_REVIEW);
const [ deleteReview ] = useMutation(DELETE_REVIEW);
const [title, setTitle] = useState("");
const [titleCharacterCount, setTitleCharacterCount] = useState(0);
const [editBody, setEditBody] = useState("");
const [editBodyCharacterCount, SetEditBodyCharacterCount] = useState(0);
console.log(editBody);
const [rating, setRating] = useState(null);
const [hover, setHover] = useState(null);
console.log()
const handleTitleChange = (event) => {
if (event.target.value.length <= 30) {
setTitle(event.target.value);
setTitleCharacterCount(event.target.value.length);
}
};
const handleEditBodyChange = (event) => {
if (event.target.value.length <= 1000) {
setEditBody(event.target.value);
SetEditBodyCharacterCount(event.target.value.length);
}
};
const handleFormSubmit = async (event) => {
event.preventDefault();
// reviewBody = editBody;
try {
await editReview({
variables: { _id:_id, title:title, reviewBody:editBody, rating:rating },
});
// clear form value
setTitle("");
setTitleCharacterCount(0);
setEditBody("");
SetEditBodyCharacterCount(0);
setShowEditModal(false);
} catch (e) {
console.error(e);
}
};
const handleDelete = async ( _id ) => {
console.log(_id)
try {
await deleteReview({
variables: { _id },
});
setShowEditModal(false);
} catch (e) {
console.error(e);
}
}
const StarRating = () => {
return (
<div>
{[...Array(5)].map((star, i) => {
const ratingValue = i + 1;
return (
<label>
<input
type='radio'
name='rating'
value={ratingValue}
onClick={() => setRating(ratingValue)}
/>
<FontAwesomeIcon className='star'
icon='star'
size='2x'
color= {ratingValue <= (hover || rating) ? '#ffc107' : '#e4e5e9'}
onMouseEnter={() => setHover(ratingValue)}
onMouseLeave={() => setHover(null)}
/>
</label>
)
})}
<h5> {rating}/5 Stars </h5>
</div>
)
}
return (
<div>
<form
className="flex-row justify-center justify-space-between-md align-stretch"
onSubmit={handleFormSubmit}
>
<textarea
placeholder={reviewTitle}
value={title}
className="form-input col-12 col-md-9"
onChange={handleTitleChange}
></textarea>
<p className={`m-0 ${titleCharacterCount === 30 ? "text-error" : ""}`}>
Character Count: {titleCharacterCount}/30
</p>
<textarea
placeholder={reviewBody}
value={editBody}
className="form-input col-12 col-md-9"
onChange={handleEditBodyChange}
></textarea>
<p
className={`m-0 ${editBodyCharacterCount === 1000 ? "text-error" : ""
}`}
>
Character Count: {editBodyCharacterCount}/1000
</p>
<StarRating />
{/* {error && <span className="ml-2">Something went wrong...</span>} */}
<button className="btn btn-success col-12 col-md-3" type="submit">
Submit
</button>
</form>
<button className="btn btn-danger mt-1 col-12 col-md-3" type="button" onClick={() => handleDelete(_id)}>
Delete Review
</button>
</div>
);
}
export default Edit;
从“@apollo/react hooks”导入{usespation}”;
从“./../utils/mutations”导入{EDIT_REVIEW,DELETE_REVIEW}”;
从'@fortawesome/react fontawesome'导入{FontAwesomeIcon};
常量编辑=({u id,reviewTitle,reviewBody,setShowEditModal})=>{
console.log(_id);
常量[editReview]=使用变异(编辑审查);
const[deleteReview]=使用变异(DELETE_REVIEW);
const[title,setTitle]=useState(“”);
常量[titleCharacterCount,setTitleCharacterCount]=useState(0);
const[editBody,setEditBody]=useState(“”);
常量[editBodyCharacterCount,SetEditBodyCharacterCount]=useState(0);
console.log(editBody);
const[rating,setRating]=useState(null);
const[hover,setHover]=useState(null);
console.log()
const handleitlechange=(事件)=>{
if(event.target.value.length{
if(event.target.value.length{
event.preventDefault();
//reviewBody=编辑主体;
试一试{
待审({
变量:{u id:{u id,title:title,reviewBody:editBody,rating:rating},
});
//清除形式值
片名(“”);
setTitleCharacterCount(0);
setEditBody(“”);
SetEditBodyCharacterCount(0);
设置ShowEditModal(假);
}捕获(e){
控制台错误(e);
}
};
const handleDelete=async(_id)=>{
console.log(_id)
试一试{
待审({
变量:{u id},
});
设置ShowEditModal(假);
}捕获(e){
控制台错误(e);
}
}
常数星号=()=>{
返回(
{[…数组(5)].map((星,i)=>{
常数值=i+1;
返回(
设定值(额定值)}
/>
setHover(null)}
/>
)
})}
{评级}/5星
)
}
返回(
字符计数:{titleCharacterCount}/30
字符计数:{editBodyCharacterCount}/1000
{/*{错误&&出了问题…}*/}
提交
handleDelete(_id)}>
删除评论
);
}
导出默认编辑;
整个问题的体系结构有点混乱。我正试图解决这个问题以及您提到的问题的体系结构。但始终尝试使您的组件更精确
首先
您不应为每个审阅呈现模式,而应创建单个模式,然后在编辑时单击“将审阅存储在状态中”,并将该审阅传递给模式
换个新钩子
const [currentReview, setCurrentReview] = useState(null);
其次
现在Edit
按钮点击如下设置评论
<Button variant="outline-warning" size='sm' onClick={() => setCurrentReview(review)}>
<FontAwesomeIcon icon="edit" color="#FEBE10" size="lg" />Edit
</Button>
设置