微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

预填充滑块值,始终跳转回预填充 api 数据的默认状态

如何解决预填充滑块值,始终跳转回预填充 api 数据的默认状态

您好,我有一个用于评分的预填充滑块,我用来自 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_URL}account/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>
)

感谢帮助。

解决方法

按照您的一般方法,这对我来说似乎很好:

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>

,

我终于设法解决了它。我需要根据用户滑动滑块的条件将两个 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_URL}account/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>
)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。