wordpress 等待数据提取,然后渲染块

hrirmatl  于 2023-04-29  发布在  WordPress
关注(0)|答案(2)|浏览(118)

我正在为WordPress开发一个 gutenberg 块,我被逻辑卡住了。
我需要获取一些数据来填充ComboboxControl,以允许用户选择一个选项。
到目前为止,我可以使它工作,但当文章被保存和页面被重新加载,组合框的保存值不能匹配任何项目从列表中,因为它是加载后,选定的值显示为空白,即使它的存在。如果我在组合框内单击,然后在组合框外单击,最终会显示所选的值。
我不得不将apiFetch请求放在Edit函数之外,以防止对API的无休止调用,但我不确定这是否是一种好的做法。
因此,从那里我不知道如何改进我的代码或如何使用钩子,如useEffect。
我需要我的数据提取,只有 * 然后 *,呈现我的ComboboxControl与所有选项准备好。
下面是我的代码从编辑。js文件:

import { __ } from '@wordpress/i18n';
 import { useBlockProps } from '@wordpress/block-editor';
 import apiFetch from '@wordpress/api-fetch';
 import { ComboboxControl, SelectControl } from '@wordpress/components';
 import { useState, useEffect } from '@wordpress/element';
 import './editor.scss';

 var options = [];
 
 apiFetch( { path: '/wp/v2/posts/?per_page=-1' } ).then( ( posts ) => {
     console.log( posts );
     if ( posts.length ) {
         posts.forEach( ( post ) => {
             options.push( { value: post.id, label: post.title.rendered } );
         } );
     }
 }, options );

 export default function Edit( { attributes, setAttributes } ) {
     const blockProps = useBlockProps();
 
     const [filteredOptions, setFilteredOptions] = useState( options );
 
     const updateGroupId = ( val ) => {
         setAttributes( { GroupId: parseInt( val ) } );
     }
 
 
     return (
         <div {...blockProps}>
 
             <ComboboxControl
                 label="Group"
                 value={attributes.GroupId}
                 onChange={updateGroupId}
                 options={filteredOptions}
                 onFilterValueChange={( inputValue ) =>
                     setFilteredOptions(
                         options.filter( ( option ) =>
                             option.label
                                 .toLowerCase()
                                 .indexOf( inputValue.toLowerCase() ) >= 0
                         )
                     )
                 }
             />
         </div>
     );
 }
vlju58qv

vlju58qv1#

我也有同样的问题。..在这里添加我的代码,因为它略有不同,可能有助于找到解决方案

const { registerBlockType } = wp.blocks;
const { ComboboxControl } = wp.components;
import { useState, useEffect } from '@wordpress/element';
import apiFetch from '@wordpress/api-fetch';

registerBlockType('hm/cptSelect', {
  title: 'cptSelect',
  category: 'common',
  icon: 'smiley',
  attributes: {
    post_id: {
      type: 'number',
      default: 0,
    },
  },
  edit: props => {
    const { attributes, setAttributes } = props;

    //states
    const [posts, setPosts] = useState([]);
    const [filteredOptions, setFilteredOptions] = useState(posts);
    //funcs
    const apirequiest = async () => {
      const res = await apiFetch({ path: '/wp/v2/posts' });
      const options = await res.map(post=> {
        return { value: post.id, label: post.title.rendered };
      });
      setPosts(options);
      return;
    };
    //effects
    useEffect(() => {
      apirequiest();
    }, []);

    return (
      <>
        <ComboboxControl
          onFilterValueChange={inputValue =>
            setFilteredOptions(
              posts.filter(option =>
                option.label.toLowerCase().includes(inputValue.toLowerCase())
              )
            )
          }
          label='PostSelect'
          value={attributes.post}
          onChange={value => setAttributes({ post_id: value })}
          options={filteredOptions}
        />
      </>
    );
  },

  save: props => {
    const { attributes } = props;

    // apiFetch({ path: `/wp/v2/posts${attributes.post_id}` }).then(res => {
    //   setPostsData(res[0]);
    // });
    return (
      <>
        <div>{attributes.post_id}</div>
      </>
    );
  },
});
mepcadol

mepcadol2#

我认为你需要一些useEffect与你的API结果作为一个依赖,这对我来说确实有效,比如

const [filteredOptions, setFilteredOptions] = useState();
  useEffect(() => {
    setFilteredOptions(options);
  }, [options, setFilteredOptions]);

很可能你需要一个条件围绕你的控制,即

{ filteredOptions ? (
   <ComboboxControl...
   />
   ) : null }

相关问题