我是新来对Hooks做出反应的人(我应该说:甚至还没有开始),但是在这个小问题上我需要帮助。该组件可渲染星星,并允许用户选择等级。我想将{starSelected}值从此组件传递到父组件。
import React, { useState } from "react";
import "./styles.css";
const Star = ({ selected = false, onClick = f => f }) => (
<div className={selected ? "star selected" : "star"} onClick={onClick} />
);
const StarRating = ({ totalStars }) => {
const [starsSelected, selectStar] = useState(0);
return (
<div className="star-rating">
{[...Array(totalStars)].map((n, i) => (
<Star
key={i}
selected={i < starsSelected}
onClick={() => selectStar(i + 1)}
/>
))}
<p>
{starsSelected} of {totalStars} stars
</p>
</div>
);
};
我将不胜感激!
父组件
class RatingNFeedback extends Component {
constructor(props) {
super(props);
this.state = {
user: {},
modal: false,
ratings: '',
feedback: '',
feedbackTitle: '',
errors: {}
};
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState(prevState => ({
modal: !prevState.modal,
ratings: '',
feedback: '',
feedbackTitle: ''
}));
}
handleRating = (assetId, accessToken) => {
const {rating, feedback, feedbackTitle} = this.state;
const ratings = {
rating,
feedbackTitle,
feedback,
asset: assetId
};
this.props.addRatingNComment(ratings, accessToken);
this.toggle();
};
onChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
isModalOpen() {
return this.state.modal;
}
render() {
const {ratingCount, commentCount, assetId, accessToken} = this.props;
let stars = [];
//loop 5 times for stars
for (let i = 1; i <= 5; i++) {
let path = require('../../assets/rateFull.svg');
if (i > ratingCount) {
path = require('../../assets/RateZero.svg');
}
stars.push(<img src={path} alt="" className="card-category-rating" />);
}
let userpic = defaultPic;
if (this.props.user) {
userpic =
'http://people.com/User%20Photos/Profile%20Pictures/' +
this.props.user.profile +
'_LThumb.jpg';
}
return (
<React.Fragment>
<Modal
isOpen={this.isModalOpen()}
toggle={this.toggle}
//style={{height: '500px', width: '500px'}}
centered
className="modal"
animation="true"
>
<ModalHeader toggle={this.toggle} className="modal-header">
<span className="modal-title"> How would you rate this report? </span>
</ModalHeader>
<ModalBody className="modal-body ">
<div className="rating-modal-header">
{' '}
<div className=" image-name-box">
<div className="circular-landscape image-box">
<img src={userpic} alt="Employee Image" className="user-profile" />{' '}
</div>
<div className="name-box">
{' '}
<p className="normal-text-2">
{' '}
{`${this.props.userName} ${this.props.familyName}`}{' '}
</p>{' '}
<p className="small-text-2 "> Your review will be posted on Our Website.</p>
</div>
</div>{' '}
</div>
<div className="heading3">Your Ratings</div>
<StarRating totalStars={5} />
<FormTextInput
label="Your Feedback:"
name="feedbackTitle"
value={this.state.feedbackTitle}
onChange={this.onChange}
placeholder="Title goes here..."
type="text"
/>
<FormTextInput
//label="Your Feedback:"
name="feedback"
value={this.state.feedback}
onChange={this.onChange}
placeholder="Write your feedback here..."
type="textarea"
/>
</ModalBody>
<ModalFooter>
<Button
color="primary"
onClick={() => this.handleRating(this.props.assetId, this.props.accessToken)}
>
Submit
</Button>{' '}
<Button color="secondary" onClick={this.toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
</React.Fragment>
);
}
}
答案 0 :(得分:4)
这可以通过将功能从父组件传递到子组件中,然后调用该函数以更新父组件中的状态来完成。如果需要,您也可以使用此方法完全管理父级中的状态,但是本示例不这样做。
父组件:
import React, { useState } from "react";
import "./styles.css";
const ParentComponent = () => {
const [selectedStar, setSelectedStar] = useState();
const updateStars = (star) => {
setSelectedStar(star);
}
return (
<StarRating
totalStars={10}
onStarUpdate={updateStars}
/>
);
}
然后是星标部分:
import React, { useState } from "react";
import "./styles.css";
const Star = ({ selected = false, onClick = f => f }) => (
<div className={selected ? "star selected" : "star"} onClick={onClick} />
);
const StarRating = ({ totalStars, onStarUpdate }) => {
// you should call your 'setter' `set` and then the name of the const
// rather than 'selectStar'
const [starsSelected, setStarsSelected] = useState(0);
const handleOnClick = (index) => {
setStarsSelected(index + 1);
// this next line will update the state in the parent component
onStarUpdate(index + 1);
}
return (
<div className="star-rating">
{[...Array(totalStars)].map((n, i) => (
<Star
key={i}
selected={i < starsSelected}
onClick={() => handleOnClick(i)}
/>
))}
<p>
{starsSelected} of {totalStars} stars
</p>
</div>
);
};
通过将功能从父级传递到子级,然后在子级中调用它,可以更新父级中的状态。
就像我说的那样,您也可以使用它来完全处理状态,然后可以这样编写StarRating:
<StarRating
totalStars={10}
onStarUpdate={updateStars}
selectedStar={selectedStar}
/>
答案 1 :(得分:0)