簡體   English   中英

單擊單選按鈕關閉手風琴

[英]Close accordions on radio button click

我的 React Native 應用程序中有一個來自 galio 框架的手風琴組件。 我用 api 數據填充它。 如果您單擊標題,手風琴將關閉,但我希望它在 select 單選按鈕時關閉。 這是我的代碼:

const Step3 = () => {
  const [questions, setQuestions] = useState([]);
  const [answers, setAnswers] = useState([]);
  const [icon, setIcons] = useState([]);
  const [iconColor, setIconsColor] = useState([])
  const [refreshing, setRefreshing] = useState(true);

  const getQuestions = async () => {
    const locale = i18next.language; // TODO: get current locale
    const response = await apiStandarts.get(`/questions?locale=${locale}`, {
      params: { active: 1, _sortId: [1,2] , _sort: "sortId:ASC"},
    });
    setRefreshing(false)
    setQuestions(response.data);
  };
  const isOptionSelected = (option) => {
    const answer = answers[option.question];
    if (answer) {
      return option.id == answer.id;
    }
    return false;
  };

  const questionIcon = async () => {
    const response = await apiStandarts.get(`/commitments-icons`);
    setIcons(response.data)
  }

  const questionIconColor = async () => {
    const response = await apiStandarts.get(`/commitments`);
    setIconsColor(response.data)
  }


  const objectMap = (obj, fn) =>
    Object.fromEntries(
      Object.entries(obj).map(([k, v], i) => [k, fn(v, k, i)])
    );
  const newAnswers = objectMap(answers, (item) => {
    return [item.id, item.description];
  });

  // useEffect(() => {
  //   questionIcon();
  // }, []);
  useEffect(() => {
    questionIcon();
    getQuestions();
  }, []);

  const OptionList = (groupOption) => {
    return (
      groupOption.options.map((item, index) => {
        const clickedRadio = () => {
          const selectedOption = { [item.question]: { ...item } };
          setAnswers({ ...answers, ...selectedOption });
        };
        let status = isOptionSelected(item) ? true : false;
        return (

          <Radio
          initialValue={status}
          label={item.description}
          onChange={() => clickedRadio()}
          color="rgba(0,0,0,.54)"
          radioInnerStyle={{backgroundColor: "#3671a6"}}
          labelStyle={ styles.label}
          containerStyle={{ width: 300, padding: 5 }}
        />
        );
      })
    );
  };




  return (
    <View style={styles.container}>
      <Text style={{ fontWeight: "bold", fontSize: 12, color: "#6B24" }}>
        {t("Choose an option/Scroll for more questions")}
      </Text>

      <FlatList
        data={questions}
        keyExtractor={(result) => result.id.toString()}
        contentContainerStyle={{ padding: 5, paddingBottom: 5 }}
        refreshControl={<RefreshControl refreshing={refreshing} onRefresh={getQuestions} />}
        renderItem={({ item, index }) => {
          const arr = [item.commitments[0].commitment_icon];
          const questIcon = arr.filter(i => Boolean(i)).map(id => icon.find(o => o.id === id)?.image?.url);
          const imgUrl = APIURL + questIcon;
          function iconBgColor(){
            let bgColor
            switch (item.commitments[0].commitment_icon) {
              case 1:
                bgColor="#78bad3"
                break;
              case 3:
                bgColor = "#027a95"
                break;
              case 6:
                bgColor = "#027a95"
                break;
              case 4:
                bgColor = '#1fc191'
                break;
                case 5:
                bgColor = '#78bad3'
                break;
              case 2:
                bgColor = "#e4da4d"
                break;
              case 7:
                bgColor = "#1fc191"
                break;
              default:
                bgColor= "#fff"
                break;
            }
              return bgColor;
          }
          const backgroundColor = iconBgColor(item.commitments[0].commitment_icon)
          const data = [
            {
              
              title: (<>
               <View style={[styles.iconWrapper,{backgroundColor: backgroundColor}]}>
                 {
                   imgUrl.indexOf('.svg') > 0 ? <SvgUri uri={APIURL + questIcon} height={20} width={20} style={styles.iconColor}/> : null
                 } 
                </View>
                
                <Text style={styles.text}>{item.sortId}.</Text>
                <Text style={styles.text} key={item.description}>{item.description}</Text>

              </>),
              content:<View><OptionList key={item?.question_options.id} options={item?.question_options}></OptionList></View>
            },
          ];


          return (
            <View style={styles.groupOptions} key={index}>
              <Accordion style={styles.accordion} headerStyle={styles.headerStyle} contentStyle={styles.contentStyle} dataArray={data} opened={index} />
            </View>
          );
        }}
      />
    </View>
  );
};


任何想法如何實現我想要的? 任何答案將不勝感激,謝謝。

您可以為開放索引管理 state 並將其傳遞給 accrodian

你有下一個代碼:

<Accordion
  style={styles.accordion}
  headerStyle={styles.headerStyle}
  contentStyle={styles.contentStyle}
  dataArray={data}
  opened={index} // here you should have "isAccordionOpen"
/>

並在您的 Step3 組件中處理 state 中的變量。

在這個 function 你應該改變這個變量“isAccordionOpen”

const clickedRadio = () => {
  const selectedOption = { [item.question]: { ...item } };
  setAnswers({ ...answers, ...selectedOption });
}

正如我在文檔和 Galio 庫中檢查的那樣,在第一個渲染周期之后似乎沒有管理 Accordion 的道具。

我們最初只能在第一次渲染時管理 Accordion。

如果您必須管理它,那么您必須在 Galio 庫代碼中進行更改。

在這里我附上示例代碼庫,希望它可以幫助你。

示例代碼:

import React, { useState } from 'react'
import { View } from 'react-native'
import { Accordion, Block, Checkbox } from 'galio-framework';

const App = () => {
  const [openIndex, setOpenIndex] = useState(-1)

  const radioClickHandler = (id, status) => {
    setOpenIndex(-1)
  }

  const data = [
    {
      title: "First Chapter",
      content: (
        <Checkbox
          onChange={radioClickHandler.bind(null, 'first')}
          color="primary"
          label="Primary Checkbox"
        />
      )
   },
   {
    title: "Second Chapter",
    content: (
        <Checkbox
          onChange={radioClickHandler.bind(null, 'second')}
          color="primary"
          label="Secondary Checkbox"
        />
      )
    }
  ]

  const onOpen = (prop) => {
    setOpenIndex(prop?.title === "First Chapter" ? 0 : 1)
  }

  return (
    <View style={{ flex: 1, justifyContent: 'center' }}>
      <Block style={{ height: 200 }}>
        <Accordion
          dataArray={data}
          opened={openIndex}
          onAccordionOpen={onOpen}
        />
      </Block>
    </View>
  )
}

export default App

這是管理折疊手風琴組件的庫代碼中的更改。

文件路徑:'node_modules/galio-framework-src-Accordion.js'

添加下面的代碼

  const [selected, setSelected] = useState(opened);

  useEffect(() => {
    setSelected(opened)
  }, [opened])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM