预填充滑块值,总是跳回预填充 api 数据的默认状态
Posted
技术标签:
【中文标题】预填充滑块值,总是跳回预填充 api 数据的默认状态【英文标题】:Prefilled slider value, jumps always back to default state of prefilled api data 【发布时间】:2021-09-19 06:15:43 【问题描述】:您好,我有一个用于评级的预填充滑块,我用 API 中的数据预填充它,如果用户滑动我喜欢更新 API 数据库。一切正常,除了滑块总是通过 useEffect 跳回到预填充的值。如何更改状态以使用户的值优先于预填充的值?
这是我的代码:
const [ user ] = useContext(Context);
const location = useLocation();
const pathname = location;
const splitLocation = pathname.split("/");
const movieId = splitLocation[2];
const [ MovieResults, setMovieResults ] = useState([]);
const [ value, setValue ] = useState(5);
useEffect(() =>
let isMounted = true;
fetch(`$API_URLaccount/xxxxxxxx/rated/movies?api_key=$API_KEY&session_id=$user.sessionId&sort_by=created_at.desc`)
.then(res => res.json())
.then(data => isMounted ? setMovieResults(data.results) : null)
.then(isMounted ? MovieResults.forEach((arrayItem) =>
if(arrayItem.id.toString() === movieId.toString())
setValue(arrayItem.rating);
) : null)
return () => isMounted = false ;
,[user.sessionId, MovieResults, movieId]);
const changeSlider = (e) =>
// This value should override the default value from the api
setValue(e.currentTarget.value);
;
return (
<div>
<input
type="range"
min="1"
max="10"
className="rate-slider"
value=value
onChange=e => changeSlider(e)
/>
value
<p>
<button className="rate-button" onClick=() => callback(value)>Rate</button>
</p>
</div>
)
感谢您的帮助。
【问题讨论】:
这对我来说似乎很好用。你能显示minimal reproducible example吗? 【参考方案1】:按照你的一般方法,这对我来说似乎很好:
const fetch = () => new Promise(resolve => setTimeout(() =>
resolve(json: () => (rating: 4))
, 1000));
const App = () =>
const [sliderVal, setSliderVal] = React.useState(0);
const [loading, setLoading] = React.useState(true);
React.useEffect(() =>
fetch("foo")
.then(res => res.json())
.then(data =>
setLoading(false);
setSliderVal(data.rating);
);
, []);
const handleSliderChange = evt =>
setSliderVal(evt.target.value);
;
return (
<div>
loading
? <p>loading...</p>
: <div>
<input
type="range"
min="1"
max="10"
value=sliderVal
onChange=handleSliderChange
/>
sliderVal
</div>
</div>
);
;
ReactDOM.render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
【讨论】:
您好,感谢您的回复,但超时应该做什么?我终于设法通过使用 ref (useRef()) 来解决它。 很高兴你成功了!我在嘲笑fetch
以返回虚假数据,这样代码就可以在没有外部依赖的情况下运行和重现。【参考方案2】:
我终于设法解决了。我需要根据用户滑动滑块的条件,将两个 setValue 中的一个优先于另一个。到目前为止,我还不知道 useRef,用这个钩子我可以管理它。代码如下:
const [ user ] = useContext(Context);
const location = useLocation();
const pathname = location;
const splitLocation = pathname.split("/");
const movieId = splitLocation[2];
const [ MovieResults, setMovieResults ] = useState([]);
const [ value, setValue ] = useState(5);
const ref = useRef(0);
useEffect(() =>
let isMounted = true;
fetch(`$API_URLaccount/jensgeffken/rated/movies?api_key=$API_KEY&session_id=$user.sessionId&sort_by=created_at.desc`)
.then(res => res.json())
.then(data => isMounted ? setMovieResults(data.results) : null)
.then(isMounted ? MovieResults.forEach((arrayItem) =>
if(arrayItem.id.toString() === movieId.toString())
//console.log(ref.current)
if(ref.current === 0)
setValue(arrayItem.rating);
) : null)
return () => isMounted = false ;
,[user.sessionId, MovieResults, movieId]);
const handleSlide = (e) =>
ref.current = e.currentTarget.value
setValue(ref.current);
return (
<div>
<input
type="range"
min="1"
max="10"
className="rate-slider"
value=value
onChange=e => handleSlide(e)
/>
value
<p>
<button className="rate-button" onClick=() => callback(value)>Rate</button>
</p>
</div>
)
【讨论】:
以上是关于预填充滑块值,总是跳回预填充 api 数据的默认状态的主要内容,如果未能解决你的问题,请参考以下文章